无法使用 LINQ to XML 循环遍历 xml 文档

Posted

技术标签:

【中文标题】无法使用 LINQ to XML 循环遍历 xml 文档【英文标题】:Unable to use LINQ to XML to loop through xml document 【发布时间】:2021-06-03 14:55:04 【问题描述】:

我正在尝试使用 LINQ 获取以下 XML 文档的元素值,但我得到“对象引用未设置为对象的实例。”;

XML:

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

  <ns1:GetContactResponse soapenv:encodingStyle=http://schemas.xmlsoap.org/soap/encoding/ xmlns:ns1=http://DefaultNamespace>

     <GetContactReturn xsi:type="ns2:Response" xmlns:ns2=http://getContact.contact.V300>

        <Contact xsi:type="ns3:Contact" xmlns:ns3=http://_contact.contact.V300>

           <Address xsi:type="xsd:string">123 test</Address>

           <Address2 xsi:type="xsd:string"/>

           <City xsi:type="xsd:string">Los Angeles</City>

           <CountryCode xsi:type="xsd:string">US</CountryCode>

           <StateCode xsi:type="xsd:string">CA</StateCode>

           <ZipCode xsi:type="xsd:string">90001</ZipCode>

        </Contact>

        <Errors soapenc:arrayType="ns4:Error[0]" xsi:type="soapenc:Array" xmlns:ns4=http://response.base.V300 xmlns:soapenc=http://schemas.xmlsoap.org/soap/encoding//>

        <IsSuccessful xsi:type="xsd:boolean">true</IsSuccessful>

        <RecordCount xsi:type="xsd:double">1.0</RecordCount>

     </GetContactReturn>

  </ns1:GetContactResponse>

   </soapenv:Body>

 </soapenv:Envelope>

我正在使用以下循环:

using (StreamReader rd = new StreamReader(services.GetResponseStream()))

   
                        var ServiceResult = rd.ReadToEnd();

                        XDocument xdoc = new XDocument();

                        xdoc = XDocument.Parse(ServiceResult);

                        var xDocResult = (from x in xdoc.Descendants("Contacts")

                                          select new Location

                                          

                                              Address = x.Element("Address").Value,

                                              Address2 = x.Element("Address2").Value,

                                              city = x.Element("City").Value,

                                              statecode = x.Element("StateCode").Value,

                                              zipcode = x.Element("ZipCode").Value

                                          );

我假设这是因为没有根。如何获取各个元素的值?

【问题讨论】:

【参考方案1】:

您的 xml 有很多错误。我正在使用 StringReader。您应该替换为 StreamReader。这是更正

<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>
    <ns1:GetContactResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://DefaultNamespace">
      <GetContactReturn xsi:type="ns2:Response" xmlns:ns2="http://getContact.contact.V300">
        <Contact xsi:type="ns3:Contact" xmlns:ns3="http://_contact.contact.V300">
          <Address xsi:type="xsd:string">123 test</Address>
          <Address2 xsi:type="xsd:string"/>
          <City xsi:type="xsd:string">Los Angeles</City>
          <CountryCode xsi:type="xsd:string">US</CountryCode>
          <StateCode xsi:type="xsd:string">CA</StateCode>
          <ZipCode xsi:type="xsd:string">90001</ZipCode>
        </Contact>
        <Errors soapenv:arrayType="ns4:Error[0]" xsi:type="soapenc:Array" xmlns:ns4="http://response.base.V300 xmlns:soapenc=http://schemas.xmlsoap.org/soap/encoding"/>
        <IsSuccessful xsi:type="xsd:boolean">true</IsSuccessful>
        <RecordCount xsi:type="xsd:double">1.0</RecordCount>
      </GetContactReturn>
    </ns1:GetContactResponse>
  </soapenv:Body>
</soapenv:Envelope>

这里是c#代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1

    class Program
    
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        
            string xml = File.ReadAllText(FILENAME);
            StringReader reader = new StringReader(xml);

            XDocument doc = XDocument.Load(reader);

            XElement contact = doc.Descendants().Where(x => x.Name.LocalName == "Contact").FirstOrDefault();
            XNamespace ns = contact.GetDefaultNamespace();

            string address = (string)contact.Element(ns + "Address");
            string address2 = (string)contact.Element(ns + "Address2");
            string city = (string)contact.Element(ns + "City");
            string country = (string)contact.Element(ns + "CountryCode");
            string state = (string)contact.Element(ns + "StateCode");
            string zip = (string)contact.Element(ns + "ZipCode");

        
    

【讨论】:

我正在通过 API 使用它。我如何将其转换为字符串? 加载方法将采用流:XDocument doc = XDocument.Load(stream); 我能够让它与您的解决方案一起使用。如果您将其添加为我帖子的答案,我会将其标记为解决方案。

以上是关于无法使用 LINQ to XML 循环遍历 xml 文档的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 linq-to-xml 查询简化此功能?

LINQ to XML 查询不返回任何结果

C# Linq to XML 读取多个带有属性的标签

使用 Linq to XML 创建基于类/模型的现有对象 - 工作,但有更好的方法吗?

LINQ to XML简介

LINQ to XML