Reputation: 1184
I wish to find the element
r with s:id = {5FF71EB5-BE2D-49DC-9442-B3DCE15067C9}
and its <rule>
with the
uid="{00000000-0000-0000-0000-000000000000}"
and then in the end output the value of s:name ("Bar1")
i have written this piece of xpath, that does exactly that.
string(//r[@s:id='{5FF71EB5-BE2D-49DC-9442-B3DCE15067C9}']//rule[@uid='{00000000:0000:0000:0000:000000000000}']/@s:name)
Validated at: 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>
The way i execute the Xpath is like this:
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;
My error is: Namespace Manager or XsltContext needed. This query has a prefix, variable, or user-defined function.
I have through a lot of digging around figured that my namespaces are not properly set. But i cannot for the life of me figure out, what i am doing wrong.
How are my namespace assignments supposed to look like?
Upvotes: 1
Views: 628
Reputation: 6957
You have to provide the namespace manager to the navigator. That takes care of the exception but SelectSingleNode was returning null. So I changed the XPath (prepended // to search all nodes). This finds the node but Value property is empty string so I changed it to OuterXml. My final version is as below:
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>"
Upvotes: 2