Search code examples
c#xmlxpathpathxelement

Get XElement with XPathSelectElement


I have a XML file and loaded the specific tag <Acct> to an XElement. From this XElement in want to give a path to get the specific child <BIC> element. I don't wan't to use the Descendates() method. I tried using XPathSelectElement to get the job done but it always return null. The XML Snippet i have looks something like this:

<Acct>
  <Id>
    <IBAN>TestIban</IBAN>
  </Id>
  <Ccy>EUR</Ccy>
  <Svcr>
    <FinInstnId>
      <BIC>TestBic</BIC>
      <ClrSysMmbId>
        <ClrSysId>
          <Cd>TestSysId</Cd>
        </ClrSysId>
        <MmbId>TestMemberId</MmbId>
      </ClrSysMmbId>
      <Nm>TestName</Nm>
      <PstlAdr>
        <AdrLine>TestAdrLine</AdrLine>
      </PstlAdr>
      <Othr>
        <Id>OtherId</Id>
        <Issr>Issr</Issr>
      </Othr>
    </FinInstnId>
  </Svcr>
</Acct>

Like i said the XElement i have is the tag called acct. I tried now following to get the <BIC> tag:

 var bic = acct.XPathSelectElement("Svrc/FinInstnId/BIC");
    var bic = acct.XPathSelectElement("/Svrc/FinInstnId/BIC");
    var bic = acct.XPathSelectElement("./Svrc/FinInstnId/BIC");
    var bic = acct.XPathSelectElement("Svrc//FinInstnId//BIC");
    var bic = acct.XPathSelectElement("//Svrc//FinInstnId//BIC");
    var bic = acct.XPathSelectElement(".//Svrc//FinInstnId//BIC");
    var bic = acct.XPathSelectElement("Acct/Svrc/FinInstnId/BIC");
    var bic = acct.XPathSelectElement("/Acct/Svrc/FinInstnId/BIC");
    var bic = acct.XPathSelectElement("./Acct/Svrc/FinInstnId/BIC");
    var bic = acct.XPathSelectElement("Acct//Svrc//FinInstnId//BIC");
    var bic = acct.XPathSelectElement("//Acct//Svrc//FinInstnId//BIC");
    var bic = acct.XPathSelectElement(".//Acct//Svrc//FinInstnId//BIC");

But all of these returning null. I found this article and they are doing in my point of view exactly the same: https://codereview.stackexchange.com/questions/204464/get-a-xelement-at-a-given-path

SO my question is how do i use the XPathSelectElement method from my XElement to get a child like the tag as XElement?

Edit:

I inspected the XElement in Debug Mode with the Text Visualizer. The XML in the Element looks like the following (The values of the elements are different but this shouldn't change the problem):

 <Acct xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02">
  <Id>
    <IBAN>TestIban</IBAN>
  </Id>
  <Ccy>EUR</Ccy>
  <Svcr>
    <FinInstnId>
      <BIC>TestBic</BIC>
      <ClrSysMmbId>
        <ClrSysId>
          <Cd>Cd</Cd>
        </ClrSysId>
        <MmbId>TestMbmId</MmbId>
      </ClrSysMmbId>
      <Nm>SomeName</Nm>
      <PstlAdr>
        <AdrLine>Address</AdrLine>
      </PstlAdr>
      <Othr>
        <Id>Id</Id>
        <Issr>Issr</Issr>
      </Othr>
    </FinInstnId>
  </Svcr>
</Acct>

Solution

  • Code works fine

    var xmlString = @"<root>
    <Acct>
      <Id>
        <IBAN>TestIban</IBAN>
      </Id>
      <Ccy>EUR</Ccy>
      <Svcr>
        <FinInstnId>
          <BIC>TestBic</BIC>
          <ClrSysMmbId>
            <ClrSysId>
              <Cd>TestSysId</Cd>
            </ClrSysId>
            <MmbId>TestMemberId</MmbId>
          </ClrSysMmbId>
          <Nm>TestName</Nm>
          <PstlAdr>
            <AdrLine>TestAdrLine</AdrLine>
          </PstlAdr>
          <Othr>
            <Id>OtherId</Id>
            <Issr>Issr</Issr>
          </Othr>
        </FinInstnId>
      </Svcr>
    </Acct>
    </root>";
    
    XDocument doc = XDocument.Parse(xmlString);
    XElement acct = doc.XPathSelectElement("root/Acct");
    XElement element = acct.XPathSelectElement("Svcr/FinInstnId/BIC");
    Console.WriteLine(element.Value);
    //print "TestBic"
    

    are you sure acct contain right XElement?

    update with namespace

    XDocument doc = XDocument.Parse(xmlString);
    var reader = doc.CreateReader();
    XmlNamespaceManager nsmgr = new XmlNamespaceManager(reader.NameTable);
    nsmgr.AddNamespace("ns", "urn:iso:std:iso:20022:tech:xsd:camt.053.001.02");
    XElement acct = doc.XPathSelectElement("//ns:Acct", nsmgr);
    XElement element = acct.XPathSelectElement("*[local-name() = 'Svcr']/*[local-name() = 'FinInstnId']/*[local-name() = 'BIC']");
    var anotherWay = acct.XPathSelectElement("ns:Svcr/ns:FinInstnId/ns:BIC", nsmgr);
    

    with local-name() you can ignore namespace