Search code examples
c#xmllinq-to-xmlargumentexceptionxmlexception

Why does XName.Get throw an ArgumentException instead of an XmlException for names starting with '{'?


I've been doing some testing of XML in .NET, and discovered that a lot of valid name characters are not allowed. In almost all cases, I get an XmlException on seemingly valid characters.

The XmlException is thrown from System.Xml.dll, with this stack trace:

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

However, in the case where a name starts with the '{' character (hex value 0x7B), I get an ArgumentException instead, from System.Xml.Linq.dll, with the following stack trace:

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

Strangely, this only applies when "{" is the first character in the name. If it appears later in the name, I get the same exception and stack trace as all the other "invalid" characters.

Since I'm trying to specifically catch these exceptions to wrap with and throw my own exception, I was hoping (reasonably so, I would think) that they would all throw the same exception.

Why does this throw an ArgumentException instead of an XmlException?


Solution

  • Check out the MSDN documentation for XName.Get:

    expandedName

    Type: System.String
    A String that contains an expanded XML name in the format {namespace}localname.

    When you begin the string parameter with "{", it handles the name differently because it's expecting a namespace.

    Here's the source for the method, via 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);
    }