我希望找到元素
r with s:id = {5FF71EB5-BE2D-49DC-9442-B3DCE15067C9}
及其<rule>
与
uid="{00000000-0000-0000-0000-000000000000}"
然后在最后输出s:name ("Bar1")
我写过这段xpath,就是这样。
string(//r[@s:id='{5FF71EB5-BE2D-49DC-9442-B3DCE15067C9}']//rule[@uid='{00000000:0000:0000:0000:000000000000}']/@s:name)
在http://codebeautify.org/Xpath-Tester
验证<r xmlns:p="p" xmlns:s="s" p:p="1">
<d>
<r s:id="{5FF71EB5-BE2D-49DC-9442-B3DCE15067C9}" > -- this one
<rls>
<ruleset>
<rule uid="{6D78B8A0-4A3D-4B73-8282-2954047089C6}" s:name="Foo">
</rule>
<rule uid="{35255912-743A-4CBC-909E-9DA3BBFD0F36}" s:name="FooBar">
</rule>
<rule uid="{A1FF1DD0-8D2E-4F1A-94D1-665B1F4E2074}" s:name="Foo1">
</rule>
<rule uid="{00000000-0000-0000-0000-000000000000}" s:name="Bar1"> --
</rule>
</ruleset>
</rls>
</r>
<r uid="{864C965D-42D8-426F-9A94-BAEA11EA1CCA}">
<rls>
<ruleset>
<rule uid="{8C215312-B610-4A10-9DC7-E3FE226D948B}" s:name="Fooo">
</rule>
<rule uid="{00000000-0000-0000-0000-000000000000}" s:name="Baar">
</rule>
</ruleset>
</rls>
</r>
</d>
</r>
我执行Xpath的方式是这样的:
var xmlStringReader = new StringReader(xmlfile);
XmlReaderSettings set = new XmlReaderSettings();
set.ConformanceLevel = ConformanceLevel.Fragment;
XPathDocument doc =
new XPathDocument(XmlReader.Create(xmlStringReader, set));
XPathNavigator nav = doc.CreateNavigator();
var xmlnsManager = new XmlNamespaceManager(nav.NameTable);
xmlnsManager.AddNamespace("p", "p" );
xmlnsManager.AddNamespace("s", "s" );
var xpath ="r[@s:id='{5FF71EB5-BE2D-49DC-9442-B3DCE15067C9}']//rule[@uid='{00000000-0000-0000-0000-000000000000}']";
string result = nav.SelectSingleNode(xpath).Value;
我的错误是:需要命名空间管理器或XsltContext。此查询具有前缀,变量或用户定义的函数。
我经历了很多挖掘,认为我的命名空间没有正确设置。但我不能为我的生活弄清楚,我做错了什么。
我的命名空间分配应该如何?
答案 0 :(得分:2)
您必须向导航器提供命名空间管理器。这会处理异常,但SelectSingleNode返回null。所以我更改了XPath(前置//搜索所有节点)。这会找到节点但Value属性为空字符串,所以我将其更改为OuterXml。我的最终版本如下:
var xpath = "//r[@s:id='{5FF71EB5-BE2D-49DC-9442-B3DCE15067C9}']//rule[@uid='{00000000-0000-0000-0000-000000000000}']";
var result = nav.SelectSingleNode(xpath, xmlnsManager);
Console.WriteLine(result.OuterXml);
// Prints: "<rule uid=\"{00000000-0000-0000-0000-000000000000}\" s:name=\"Bar1\" xmlns:s=\"s\"></rule>"