简体   繁体   English

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

[英]Parsing SOAP response with LINQ to XML - how to get nested nodes under parent?

I have an SOAP response that looks similar to this: 我有一个类似于这样的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>

I've been able to successfully extract the <get LoginResponse ...> node with the following LINQ code: 我已经能够使用以下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();

However , the call to Name = r.Element("person_name").Value gives me an Object reference not set to an instance of an object error. 但是 ,对Name = r.Element("person_name").Value的调用Name = r.Element("person_name").Value给了我一个Object reference not set to an instance of an object错误Object reference not set to an instance of an objectObject reference not set to an instance of an object

I looked into this further, and I see that if I run this query, all of the values (person_id, person_name) are in fact in the nested .Descendants().Descendants() XElement collection: 我进一步调查了这一点,我看到如果我运行此查询,所有值(person_id,person_name)实际上都是嵌套的 .Descendants().Descendants() XElement集合:

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

So, what this tells me is in my original LINQ query, I am not extracting the nodes under <getLoginResponse> correctly. 所以,这告诉我的是在我原来的LINQ查询中,我没有正确地提取<getLoginResponse>下的节点。

How can I combine this together, using ... select new User { ... } to fill my custom object? 我如何将它们组合在一起,使用... select new User { ... }来填充我的自定义对象?

Doing something like: 做类似的事情:

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

Doesn't work very well :) 不是很好:)

Thanks all for the solution - I omitted the namespace from the child elements, which caused my issue! 谢谢大家的解决方案 - 我从子元素中省略了命名空间,这导致了我的问题!

You need to add a valid namespace to your query, in your example that would be "http://foobar/webservices" , eg: 您需要在查询中添加一个有效的命名空间,在您的示例中为"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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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