为什么我无法从XPathNavigator中检索属性值?

时间:2010-02-12 13:23:18

标签: c# xml xpath

我有这样的XML:

<?xml version="1.0"?>
<a xmlns="http://mynamespace">
  <b>
    <c val="test" />
  <b>
</a>

我试图在'c'标签上找到'val'属性的值,如下所示:

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

我的问题是GetAttribute总是以空字符串形式返回。我错过了什么?


更新

似乎我可以通过将空字符串传递给GetAttribute来解决这个问题,即

string val = nav.GetAttribute("val", "");

现在我的问题是:为什么这有效?为什么'val'不属于我的命名空间,尽管XML已经针对需要'val'属性的模式进行了验证(我在上面的示例代码中意外省略了这一步,但我正在验证XML)。

2 个答案:

答案 0 :(得分:3)

默认命名空间声明不适用于属性,因此名为“val”的属性不在命名空间中,如果要访问它,则需要在不使用命名空间的情况下访问它。 将属性放入命名空间的唯一方法是给它一个带有前缀和本地名称的限定名称(例如pf:val),其中前缀绑定到命名空间(例如xmlns:pf =“http:// example。 COM / foo“的)。

答案 1 :(得分:2)

好的,我做了一些搜索并发现这是在XSD中通过schema元素的以下属性来控制的:

attributeFormDefault="qualified"

attributeFormDefault="unqualified"

默认情况下,它似乎是“不合格的”,也就是说属性永远不属于任何名称空间,只属于元素(由elementFormDefault值控制,当然)。

默认情况下强制限定属性会强制任何XML在属于该架构的所有属性上都需要前缀。

我的问题的答案似乎是空字符串是接受此选项默认值的任何模式中定义的所有属性的正确名称空间。

第6.3节here中解释了部分内容,其中还指出默认命名空间不能应用于属性 - 它们必须具有前缀,与元素不同。