使用linq-xml深入查询xElement

本文关键字:查询 xElement linq-xml 使用 | 更新日期: 2023-09-27 18:13:06

我有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>

,我试图得到RetKey元素的值,像这样

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 queryitem正在正确设置,但我在foreach循环中得到此错误

"对象引用未设置为对象的实例。"

使用linq-xml深入查询xElement

我看不出你的代码有什么明显的错误。

我假设你用的是VS?尝试在foreach的每行中使用一个断点运行以下代码,并在每一步检查局部变量,以查看哪一个. element(…)查询可能是问题所在。在每个步骤中检查locals视图中的每个变量,以查看某个xelement中是否出现了意外情况。

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;
}

您可以看到哪个变量jklmn与预期的不同,或者代码将中断并产生更多信息异常。

注意:至少在VS2015中,在locals视图中有一个小放大镜,它可以让你很好地查看xml(如果你不知道的话)。

Edit:我不知道XElement之间的差异。后代和XElement。元素,我仍然不清楚如何正确地使用级联的名称空间。参见没有或只有根命名空间。如果命名空间不固定,请参见从元素中剥离命名空间。

我认为这可能是解决方案,虽然。如果我没记错的话,你可以直接写

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

来获取该xml中的RetKey值列表。也许还可以尝试使用xdoc.Root.Descendants来避免使用第一个命名空间。