Why can't I retrieve attribute values from my XPathNavigator?
I have XML something like this:
<?xml version="1.0"?>
<a xmlns="http://mynamespace">
<b>
<c val="test" />
<b>
</a>
And I am trying to find the value of the 'val' attribute on the 'c' tag with something like this:
XmlDocument doc = new XmlDocument();
doc.Load("myxml.xml");
nsMgr = new XmlNamespaceManager(doc.NameTable);
nsMgr.AddNamespace(@"mns", "http://mynamespace");
XPathNavigator root = doc.CreateNavigator();
foreach (XPathNavigator nav in root.Select("//mns:c", nsMgr))
{
string val = nav.GetAttribute("val", NS);
Console.WriteLine("val == "+val)开发者_JAVA百科;
}
My problem is that GetAttribute always returns as an empty string. What am I missing?
Update:
It seems I can fix this by passing an empty string into GetAttribute, i.e.
string val = nav.GetAttribute("val", "");
My question is therefore now: why does this work? Why does 'val' not belong to my namespace despite the XML having been validated against a schema which requires the 'val' attribute (I accidentally omitted this step in my above sample code, but I am validating the XML).
Default namespace declarations do not apply to attributes so that attribute named 'val' is in no namespace and if you want to access it then you need to access it without using a namespace. The only way to put an attribute in a namespace is by giving it a qualified name with a prefix and local name (e.g. pf:val) where the prefix is bound to a namespace (e.g. xmlns:pf="http://example.com/foo").
Ok, I did some hunting and discovered that this is controlled in the XSD by the following attribute on the schema element:
attributeFormDefault="qualified"
or
attributeFormDefault="unqualified"
By default, it seems to be 'unqualified' which is to say that attributes never belong to any namespaces, only elements (Controlled by the elementFormDefault value, naturally).
Forcing qualified attributes by default forces any XML to require prefixes on all attributes belonging to that schema.
The answer to my question seems to be that an empty string is the correct namespace for all attributes defined in any schema that accepts the default value for this option.
Part of this is explained in Section 6.3 here which also states that the default namespace cannot apply to attributes - they must have prefixes, unlike elements.
精彩评论