1

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?

1 Answer 1

2

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>"
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.