Reputation: 471
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?
Upvotes: 0
Views: 110
Reputation: 26223
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");
Upvotes: 1
Reputation: 471
if (((XElement)xN).Value == value)
{
XNamespace myNs = ((XElement)xN).Name.Namespace;
myResultSet[0].Add(new ResultSet(file, myX.Root.Descendants(myNs + "MessageVersion").First().Value));
}
After starting from the result and not the document itself it was quite easy to extract the namespace and the value.
But this works only, because I am brute forcing the document. I found no solution to do it in a sober way... Still looking for a better solution.
Upvotes: 0