简体   繁体   中英

query deep into xElement using linq-xml

I have XML

<Envelopes>
  <Envelope   xmlns:env="http://www.w3.org/2003/05/soap-envelope">
    <Body>
      <UpdateObjectResponse xmlns="http://www.sap.com/SBO/DIS" 
                            CommandID="UpdateObject picklist">
        <RetKey>426358</RetKey>
        <RetType>156</RetType>
      </UpdateObjectResponse>
    </Body>
  </Envelope>                
  <Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
    <Body>
      <UpdateObjectResponse xmlns="http://www.sap.com/SBO/DIS" 
                            CommandID="UpdateObject picklist">
        <RetKey>426358</RetKey>
        <RetType>156</RetType>
      </UpdateObjectResponse>
    </Body>
  </Envelope>
</Envelopes>

and I am trying to get value of RetKey element like so

var query = from t in xdoc.Descendants("Envelope") select t;

foreach (XElement item in query)
{
    var k = item.Element("Body").Element("UpdateObjectResponse").Element("RetKey").Value;
}

var query and item are getting set properly, but I am getting this error within the foreach loop

"Object reference not set to an instance of an object."

I cannot see anything obvious that's wrong with your code.

I'll assume you're using VS? Try running the following code with a break point in each line of the foreach and chech the locals at each step, to see which of the .Element(..) queries might be the problem. Check each of the variables in in the locals view at each step, to see if something unexpected appears in one of the XElements.

var query = from t in xdoc.Descendants("Envelope") select t;
foreach (XElement item in query)
{
    var j = item;
    var k = item.Element("Body");
    var l = k.Element("UpdateObjectResponse");
    var m = l.Element("RetKey");
    var n = m.Value;
}

Either you will see which of the variables jklmn is different than expected, or the code will break with a more informative exception.

Note: at least in VS2015, there's a little magnifying glass in the locals view, which lets you nicely view XMLs (in case you didn't know).

Edit : I was not aware of the differences between XElement.Descendants and XElement.Elements and I am still unclear on how to do this properly with the cascaded namespaces. See Without or only root namespace . See Strip namespaces from Elements in case the namespace isn't fixed.

I think that this might be the solution, though. If I get it correctly, you can just write

XNamespace ns = "http://www.sap.com/SBO/DIS";
var klist = from t in xdoc.Descendants(ns + "RetKey") select t.Value;

to get a list of the RetKey values in that xml. Maybe also try xdoc.Root.Descendants to avoid the first namespace.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM