k3b*_*k3b 13 .net c# xpath unit-testing
我有一些默认命名空间的xml
<a xmlns='urn:test.Schema'><b/><b/></a>
Run Code Online (Sandbox Code Playgroud)
并想要数数 <b/>
我该如何定义
XmlNamespaceManager nsmgr = ????
Assert.AreEqual(2, doc.SelectNodes("//b", nsmgr).Count);
Run Code Online (Sandbox Code Playgroud)
断言变为真?
我到目前为止尝试过(使用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);
}
Run Code Online (Sandbox Code Playgroud)
Dim*_*hev 30
Run Code Online (Sandbox Code Playgroud)// This will fail with dotnet 3.5sp1. Why? //!!!! Assert.AreEqual(2, doc.SelectNodes("//b", nsmgr).Count);
这是一个FAQ.在XPath中,任何未加前缀的名称都假定为"无命名空间".为了选择属于命名空间的元素,在任何XPath表达式中,它们的名称必须以与此命名空间关联的前缀作为前缀.该AddNamespace()方法恰好用于此目的.它在特定命名空间和特定前缀之间创建绑定.然后,如果在XPath表达式中使用此前缀,则可以选择以其为前缀的元素.
它是用XPath W3C规范编写的:"节点测试中的QName使用表达式上下文中的命名空间声明扩展为扩展名.这与开始和结束标记中的元素类型名称的扩展相同除了没有使用xmlns声明的默认命名空间:如果QName没有前缀,那么命名空间URI为空".
请参阅:w3.org/TR/xpath/#node-tests.
因此,任何未加前缀的名称都被视为"无名称空间".在提供的XML文档中b,"no namespace" 中没有元素,这就是XPath表达式//b根本不选择任何节点的原因.
使用:
XmlNamespaceManager nsmanager = new XmlNamespaceManager(doc.NameTable);
nsmanager.AddNamespace("x", "urn:test.Schema");
Run Code Online (Sandbox Code Playgroud)
然后:
Assert.AreEqual(2, doc.SelectNodes("//x:b", nsmanager).Count);
Run Code Online (Sandbox Code Playgroud)
请记住:注册命名空间的全部目的是能够x在任何XPath表达式中使用前缀(在本例中).
| 归档时间: |
|
| 查看次数: |
20124 次 |
| 最近记录: |