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?
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);
}