使用LINQ to XML解析SOAP响应-如何在父节点下获取嵌套节点

本文关键字:父节点 获取 节点 嵌套 to LINQ XML 解析 响应 SOAP 使用 | 更新日期: 2023-09-27 18:22:50

我有一个SOAP响应,看起来类似于以下内容:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soapenv:Body>
    <getLoginResponse xmlns="http://<remotesite>/webservices">
        <person_id>123456</person_id>
        <person_name>John Doe</person_name>
    </getLoginResponse>
  </soapenv:Body>
</soapenv:Envelope>

我已经能够使用以下LINQ代码成功提取<get LoginResponse ...>节点:

string soapResult = rd.ReadToEnd();
XNamespace ns = "http://<remotesite>/webservices";
XDocument xDoc = XDocument.Parse(soapResult);
var respUser = (from r in xDoc.Descendants(ns + "getLoginResponse")
                select new User
                           {
                               Name = r.Element("person_name").Value
                           }).FirstOrDefault();

但是,对Name = r.Element("person_name").Value的调用会给我一个Object reference not set to an instance of an object错误。

我对此进行了进一步的研究,发现如果我运行这个查询,所有的值(person_id,person_name)实际上都在嵌套的.Descendants().Descendants() XElement集合中:

var respUser = (from r in xDoc.Descendants(ns + "getLoginResponse") 
                select r).Descendants().ToList();

所以,这个告诉我的是,在我最初的LINQ查询中,我没有正确地提取<getLoginResponse>下的节点。

如何使用... select new User { ... }填充我的自定义对象,将其组合在一起?

做一些类似的事情:

var respUser = (from r in xDoc.Descendants(ns + "getLoginResponse").Descendants()
                select new User()
                              {
                                 Name = r.Element("person_name").Value
                              }).FirstOrDefault();

工作不太好:)

感谢所有人提供的解决方案-我从子元素中省略了名称空间,这导致了我的问题

使用LINQ to XML解析SOAP响应-如何在父节点下获取嵌套节点

您需要向查询添加一个有效的命名空间,在您的示例中,该命名空间将是"http://foobar/webservices",例如:

XElement xml = XElement.Load(@"testData.xml");
XNamespace foobar = "http://foobar/webservices";
string personId = xml.Descendants(foobar + "person_id").First().Value;

您需要包含名称空间:

r.Element(ns + "person_name").Value