为什么XName.Get为以'{'开头的名称抛出ArgumentException而不是XmlException?

时间:2013-01-18 18:38:19

标签: c# xml linq-to-xml argumentexception xmlexception

我一直在用.NET测试XML,并发现a lot of valid name characters are not allowed。几乎在所有情况下,我都会在看似有效的字符上得到XmlException。

使用此堆栈跟踪从System.Xml.dll抛出XmlException:

  

at System.Xml.XmlConvert.VerifyNCName(String name,ExceptionType exceptionType)      在System.Xml.Linq.XName..ctor(XNamespace ns,String localName)      在System.Xml.Linq.XNamespace.GetName(String localName)      在System.Xml.Linq.XName.Get(String expandedName)

但是,如果名称以'{'字符(十六进制值0x7B)开头,我会从System.Xml.Linq.dll获得一个ArgumentException,其中包含以下堆栈跟踪:

  

在System.Xml.Linq.XName.Get(String expandedName)

奇怪的是,这仅适用于名称中“{”是第一个字符的情况。如果它出现在名称的后面,我会得到与所有其他“无效”字符相同的异常和堆栈跟踪。

因为我试图专门捕获这些异常以包装并抛出我自己的异常,所以我希望(合理的是,我认为)他们都会抛出相同的异常。

为什么抛出ArgumentException而不是XmlException?

1 个答案:

答案 0 :(得分:2)

查看XName.Get的{​​{3}}:

  

expandedName

     
    

输入:MSDN documentation
    一个System.String,其中包含格式为{namespace}localname

的扩展XML名称   

当您使用“{”开始字符串参数时,它会以不同的方式处理名称,因为它期望命名空间。

以下是该方法的来源,通过Reflector:

public static XName Get(string expandedName)
{
    if (expandedName == null)
    {
        throw new ArgumentNullException("expandedName");
    }
    if (expandedName.Length == 0)
    {
        throw new ArgumentException(Res.GetString("Argument_InvalidExpandedName",
            new object[] { expandedName }));
    }
    if (expandedName[0] != '{')
    {
        return XNamespace.None.GetName(expandedName);
    }
    int num = expandedName.LastIndexOf('}');
    if ((num <= 1) || (num == (expandedName.Length - 1)))
    {
        throw new ArgumentException(Res.GetString("Argument_InvalidExpandedName",
            new object[] { expandedName }));
    }
    return XNamespace.Get(expandedName, 1, num - 1).GetName(expandedName, num + 1,
        (expandedName.Length - num) - 1);
}