Search code examples
c#xmldocumentxmlnode

Unable select XmlNode by Xpath with two attributes


I have xml as a response, need to find marked red arrow node:

enter image description here

My code:

 //response to xmlDocument
 document = new XmlDocument();
 document.LoadXml(response.Content);
 XmlNamespaceManager ns = new XmlNamespaceManager(document.NameTable);
 foreach (XmlAttribute curAttribute in document.DocumentElement.Attributes)
        {
          if (curAttribute.Prefix.Equals("xmlns"))
             { ns.AddNamespace(curAttribute.LocalName, curAttribute.Value); }
         }
            
 string xpath = "//edmx:Edmx/edmx:DataServices/Schema[@Namespace='Core.Entities']/EntityType[@Name='Office']/Property[@Name='OfficeKeyNumeric']";
            XmlNode node = document.SelectSingleNode(xpath, ns);
        }

I have an error that node can't be found by given XPath, node is null.

What I tried:

with and

string xpath = "//edmx:Edmx/edmx:DataServices/Schema[@Namespace='Core.Entities' and @xmlns='http://docs.oasis-open.org/odata/ns/edm']/EntityType[@Name='Office']/Property[@Name='OfficeKeyNumeric']";
        

without and

string xpath = "//edmx:Edmx/edmx:DataServices/Schema[@Namespace='Core.Entities'][@xmlns='http://docs.oasis-open.org/odata/ns/edm']/EntityType[@Name='Office']/Property[@Name='OfficeKeyNumeric']";

Tried also with pipe |, & - nothing helped.

Why it doesn't work and is it possible to make it work in that way?

The only one working solution I'm using now is to remove xmlns="http://docs.oasis-open.org/odata/ns/edm"from XML document before loading, after that my code above works fine.

document.LoadXml(response.Content.Replace("xmlns=\"http://docs.oasis-open.org/odata/ns/edm\"", ""));

Solution

  • The Schema element and its descendants are declared in the http://docs.oasis-open.org/odata/ns/edm namespace, which must be referenced in the xpath statement you are looking for.

    string xpath = "//edmx:Edmx/edmx:DataServices/edm:Schema[@Namespace='Core.Entities']/edm:EntityType[@Name='Office']/edm:Property[@Name='OfficeKeyNumeric']";

    Make sure to have your XmlNamespaceManager initialized with these namespaces.

    XmlNamespaceManager ns = new XmlNamespaceManager(document.NameTable);
    ns.AddNamespace("edmx","http://docs.oasis-open.org/odata/ns/edmx");
    ns.AddNamespace("edm","http://docs.oasis-open.org/odata/ns/edm");