【问题标题】:query deep into xElement using linq-xml使用 linq-xml 深入查询 xElement
【发布时间】:2015-10-08 07:29:50
【问题描述】:

我有 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 循环中收到此错误

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

【问题讨论】:

  • 我不确定我做错了什么,但我现在已经尝试解决这个问题,这是我可以提出问题的最佳方式

标签: c# asp.net linq-to-xml


【解决方案1】:

我看不出你的代码有什么明显的问题。

我假设您使用的是 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 中,本地视图中有一个小放大镜,可以让您很好地查看 XML(以防您不知道)。

编辑:我不知道 XElement.Descendants 和 XElement.Elements 之间的 differences,我仍然不清楚如何使用级联命名空间正确执行此操作。 见Without or only root namespace。 如果命名空间不固定,请参阅Strip namespaces from Elements

不过,我认为this 可能是解决方案。如果我理解正确,你可以写

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 来避免使用第一个命名空间。

【讨论】:

  • J 和 K 设置正确,但 l 不是,可能是因为 updateObjectResponse 标签中的命名空间属性?
  • k 的值为 - sap.com/SBO/DIS" CommandID="UpdateObject picklist"> 426358156 UpdateObjectResponse>
  • 你试过here做了什么吗?您可能需要再次使用 .Descendants。
  • 我在 updateObjectResponse 元素中去掉了命名空间,它起作用了,谢谢@gMueller
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-24
相关资源
最近更新 更多