我有一些带有默认命名空间的xml
<a xmlns='urn:test.Schema'><b/><b/></a>
并想数 <b/>
<b/>
我该如何定义
XmlNamespaceManager nsmgr = ???? Assert.AreEqual(2, doc.SelectNodes("//b", nsmgr).Count);
这样断言变为事实?
到目前为止,我已经尝试过(使用nunit):
[Test] [Ignore("Why does this not work?")] public void __DoesNotWork_TestSelectWithDefaultNamespace() { // xml to parse with defaultnamespace string xml = @"<a xmlns='urn:test.Schema'><b/><b/></a>"; XmlDocument doc = new XmlDocument(); doc.LoadXml(xml); // fails because xpath does not have the namespace //!!!! Assert.AreEqual(2, doc.SelectNodes("//b").Count); // using XPath defaultnamespace XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable); nsmgr.AddNamespace("", "urn:test.Schema"); // This will fail with dotnet 3.5sp1. Why? //!!!! Assert.AreEqual(2, doc.SelectNodes("//b", nsmgr).Count); } [Test] public void TestSelectWithoutNamespaces_Ok() { // xml to parse without namespace string xml = @"<a><b/><b/></a>"; XmlDocument doc = new XmlDocument(); doc.LoadXml(xml); // works ok Assert.AreEqual(2, doc.SelectNodes("//b").Count); // works ok XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable); Assert.AreEqual(2, doc.SelectNodes("//b", nsmgr).Count); } [Test] public void TestSelectWithNamespacesPrefixed_Ok() { // xml to parse with defaultnamespace string xml = @"<a xmlns='urn:test.Schema'><b/><b/></a>"; XmlDocument doc = new XmlDocument(); doc.LoadXml(xml); // using XPath namespace via alias "t". works ok but xpath is to complicated XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable); nsmgr.AddNamespace("t", doc.DocumentElement.NamespaceURI); Assert.AreEqual(2, doc.SelectNodes("//t:b", nsmgr).Count); }
// This will fail with dotnet 3.5sp1. Why? //!!!! Assert.AreEqual(2, doc.SelectNodes("//b", nsmgr).Count);
这是一个常见问题解答 。在XPath中,任何不带前缀的名称都假定为“无名称空间”。为了选择属于名称空间的元素,在任何XPath表达式中,它们的名称都必须带有与此名称空间关联的前缀作为前缀。该AddNamespace()方法正是用于此目的。它在特定名称空间和特定前缀之间创建绑定。然后,如果在XPath表达式中使用此前缀,则可以选择由其前缀的元素。
AddNamespace()
它是用 XPath W3C规范 编写的:“使用表达式上下文中的命名空间声明,将节点测试中的QName扩展为扩展名称。这与在开始和结束标记中对元素类型名称进行扩展的方式相同。区别在于不使用用xmlns声明的默认名称空间:如果QName没有前缀,则名称空间URI为null”。
请参见以下 网址 : w3.org/TR/xpath/#node- tests 。
因此,任何没有前缀的名称都被认为是“无名称空间”。在提供的XML文档中b,“没有名称空间” 中没有元素,这就是XPath表达式//b根本不选择节点的原因。
b
//b
用途 :
XmlNamespaceManager nsmanager = new XmlNamespaceManager(doc.NameTable); nsmanager.AddNamespace("x", "urn:test.Schema");
及以后 :
Assert.AreEqual(2, doc.SelectNodes("//x:b", nsmanager).Count);
请记住 :注册名称空间的全部目的是能够x在任何XPath表达式中使用前缀(在这种情况下为)。
x