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

发布于 2025-01-03 12:47:51 字数 2008 浏览 0 评论 0原文

我有一个与此类似的 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 代码成功提取 节点:

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 的调用给我一个 未设置对象实例的对象引用错误。

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

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

所以,这告诉我在我的原始 LINQ 查询中,我没有正确提取 下的节点。

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

做类似的事情:

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

效果不太好:)

感谢大家的解决方案 - 我省略了子元素中的名称空间,这导致了我的问题!

I have an SOAP response that looks similar to this:

<?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:

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.

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:

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.

How can I combine this together, using ... select new User { ... } to fill my custom object?

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

巾帼英雄 2025-01-10 12:47:51

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

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

You need to add a valid namespace to your query, in your example that would be "http://foobar/webservices", e.g.:

XElement xml = XElement.Load(@"testData.xml");
XNamespace foobar = "http://foobar/webservices";
string personId = xml.Descendants(foobar + "person_id").First().Value;
檐上三寸雪 2025-01-10 12:47:51

您需要包含名称空间:

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

You need to include the namespace:

r.Element(ns + "person_name").Value
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文