Xpath无法解析XML:需要命名空间管理器或XsltContext

时间:2016-02-10 16:22:23

标签: c# xml xpath

我希望找到元素

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。此查询具有前缀,变量或用户定义的函数。

我经历了很多挖掘,认为我的命名空间没有正确设置。但我不能为我的生活弄清楚,我做错了什么。

我的命名空间分配应该如何?

1 个答案:

答案 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>"