Search code examples
c#xmlnamespacesenvelope

Overloading namespaces in xml with envelope


I have a program that iterates through XML Documents to search for values. I want to extract the version number of the document I found and add it to the search result.

The problem I encounter is, that the documents have a lot of different namespaces, and most of them have an envelope. The envelope has the same namespaceprefix like the divergent namespace in the payload of the document. I am struggeling to extract values from the payload, because I am not able to get the namespace of the inner document.

if (myX != null)
{
    XNamespace myNs;
    if (myX.Root.FirstAttribute == null)
        myNs = "";
    else
    {
        myNs = myX.Root.FirstAttribute.Value;
        var dummy2 = myX.Root.Descendants("Message").First().FirstAttribute;
        var dummy1 = myX.Root.Descendants(myNs + "Message").First().FirstAttribute;

    }


    foreach (XNode xN in myX.Root.DescendantNodes())
    {
        if (xN is XElement)
        {
            if (!wildcard)
            {
                if (((XElement)xN).Value == value)
                {
                    myResultSet[0].Add(new ResultSet(file, myX.Root.Descendants(myNs + "MessageVersion").First().Value));
                }
            }
            else if (wildcard)
            {
                if (((XElement)xN).Value.Contains(value))
                {
                    myResultSet[0].Add(new ResultSet(file, myX.Root.Descendants(myNs + "MessageVersion").First().Value));
                }
            }
        }
    }
}

I can get the ns0:Body Element, but I fail to get anything with the "http://dummy.schema.com/ss2/schemas/2.5/DESADV" namespace. The XML is something like this:

<ns0:Envelope xmlns:ns0="http://dummy.schema.com/ss2/schemas/2.3">
  <ns0:SenderILN>123456789123</ns0:SenderILN>
  <ns0:ReceiverILN>987654321987</ns0:ReceiverILN>
  <ns0:EnvelopeNumber>12345</ns0:EnvelopeNumber>
  <ns0:Body>
    <ns0:Message xmlns:ns0="http://dummy.schema.com/ss2/schemas/2.5/DESADV">
      <ns0:Header>
        <ns0:MessageType>DESADV</ns0:MessageType>
        <ns0:SenderILN>123456789123</ns0:SenderILN>1
        <ns0:ReceiverILN>987654321987</ns0:ReceiverILN>
        <ns0:MessageVersion>2.5</ns0:MessageVersion>
      </ns0:Header>
      <ns0:DESADV>
        <ns0:Payload />
      </ns0:DESADV>
    </ns0:Message>
  </ns0:Body>
</ns0:Envelope>

Is there a possibility to get to the inner message without removing the envelope first?


Solution

  • I'm not sure why you're trying to 'extract' the namespace. The namespace is part of the element name - just as you know the local name MessageVersion you should also know its namespace.

    You should be doing something like this:

    XNamespace ns = "http://dummy.schema.com/ss2/schemas/2.5/DESADV"
    
    var version = (string) doc
        .Descendants(ns + "MessageVersion")
        .Single();
    

    If for some reason you don't know or don't care about the namespace, you can just search by local name:

    var version = (string) doc
        .Descendants()
        .Single(x => x.Name.LocalName == "MessageVersion");