Linq to XML 完整的 Child Element XL 结构

Posted

技术标签:

【中文标题】Linq to XML 完整的 Child Element XL 结构【英文标题】:Linq to XML complete Child Element XL structure 【发布时间】:2020-03-03 12:31:18 【问题描述】:

我正在尝试不使用读取 xml 的旧方式并尝试 linq to xml,但我很难完成以下操作:

响应 XML

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Body>
      <PolicyResponse>
        <serviceResponse>
          <responseCode>0</responseCode>
          <responseDescription>Success</responseDescription>
          <responseDetail>Success</responseDetail>
          <paging>
            <pageNum>1</pageNum>
            <pageSize>3</pageSize>
            <totalRecords>3</totalRecords>
          </paging>
        </serviceResponse>
        <detailsResponseList>
          <detailResponse>
            <policy>
              <policySummaryInfo>
                <PolicyNumber>1199128</PolicyNumber>
                <PremiumChangeAmt>...</PremiumChangeAmt>
                <WrittenAmt>...</WrittenAmt>
                <PolicyStatusDesc>Expired</PolicyStatusDesc>
                <BillingInfo>
                  <InsuredOrPrincipal>...</InsuredOrPrincipal>
                </BillingInfo>
              </policySummaryInfo>
            </policy>
          </detailResponse>
          <detailResponse>
            <policy>
              <policySummaryInfo>
                <PolicyNumber>1199128</PolicyNumber>
                <PremiumChangeAmt>...</PremiumChangeAmt>
                <WrittenAmt>...</WrittenAmt>
                <PolicyStatusDesc>Active</PolicyStatusDesc>
                <BillingInfo>
                  <InsuredOrPrincipal>...</InsuredOrPrincipal>
                </BillingInfo>
              </policySummaryInfo>
            </policy>
          </detailResponse>
        </detailsResponseList>
      </PolicyResponse>
    </out2:getPolicySummaryResponse>
  </soapenv:Body>
</soapenv:Envelope>

我在 C# 中这样做

XDocument xdoc = new XDocument();
xdoc = XDocument.Parse(xmlResponse);

IEnumerable<XElement> items =
  from el in xdoc.Descendants("detailResponse")
   select el;

使用此代码,我可以读取机器人 detailReponse 元素,但我想要的是仅保留 XML detailResponse 结构,其中 &lt;PolicyStatusDesc&gt;&lt;/PolicyStatusDesc&gt; 等于 Active。那可能吗。我设法根据元素名称收集特定数据,但是如何使用 Linq to XML 保持整个 XML 子元素结构(detailResponse 元素及其子元素)。

谢谢

【问题讨论】:

【参考方案1】:

在您的 XML 示例中有一个无效的 &lt;/out2:getPolicySummaryResponse&gt; 已删除的标签

这是您可以用于结果的代码

 IEnumerable<XElement> items =
            from el in xdoc.Descendants("detailResponse")
            where  el.Element("policy")?.Element("policySummaryInfo")?.Element("PolicyStatusDesc")?.Value == "Active"
            select el;

【讨论】:

.完美!!感谢您的帮助!【参考方案2】:

我经常使用下面的代码,它比使用序列化得到更平坦的结果:

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

namespace ConsoleApplication1

    class Program
    
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        
            XDocument doc = XDocument.Load(FILENAME);
            XElement xPolicyResponse = doc.Descendants("PolicyResponse").FirstOrDefault();

            PolicyResponse policyResponse = new PolicyResponse(xPolicyResponse); 

        
    
    public class PolicyResponse
    
        public ServiceResponse serviceResponse  get; set; 
        public List<DetailResponse> detailResponse  get; set; 

        public PolicyResponse() 
        public PolicyResponse(XElement element)
        
            XElement xServiceResponse = element.Element("serviceResponse");
            List<XElement> xdetailResponseList = element.Descendants("detailResponse").ToList();
            serviceResponse = new ServiceResponse(xServiceResponse);
            detailResponse = xdetailResponseList.Select(x => new DetailResponse(x)).ToList();

        
    
    public class ServiceResponse
    
        public int responseCode  get; set; 
        public string responseDescription  get; set; 
        public string responseDetail  get; set; 
        public int pageNum  get; set; 
        public int pageSize  get; set; 
        public int totalRecords  get; set; 

        public ServiceResponse()  
        public ServiceResponse(XElement element)
        
            responseCode = (int)element.Element("responseCode");
            responseDescription = (string)element.Element("responseDescription");
            responseDetail = (string)element.Element("responseDetail");
            pageNum = (int)element.Descendants("pageNum").FirstOrDefault();
            pageSize = (int)element.Descendants("pageSize").FirstOrDefault();
            totalRecords = (int)element.Descendants("totalRecords").FirstOrDefault();
        
    
    public class DetailResponse
    
        public string policyNumber  get; set; 
        public string premiumChangeAmt  get; set; 
        public string writtenAmt  get; set; 
        public string policyStatusDesc  get; set; 
        public string insuredOrPrincipal  get; set;                 

        public DetailResponse()  
        public DetailResponse(XElement element)
        
            XElement xPolicySummaryInfo = element.Descendants("policySummaryInfo").FirstOrDefault();

            policyNumber = (string)xPolicySummaryInfo.Element("PolicyNumber");
            premiumChangeAmt = (string)xPolicySummaryInfo.Element("PremiumChangeAmt");
            writtenAmt = (string)xPolicySummaryInfo.Element("WrittenAmt");
            policyStatusDesc = (string)xPolicySummaryInfo.Element("PolicyStatusDesc");
            insuredOrPrincipal = (string)xPolicySummaryInfo.Descendants("InsuredOrPrincipal").FirstOrDefault();
        
    

【讨论】:

感谢您的支持!【参考方案3】:

您可以通过使用el.Descendants("PolicyStatusDesc") 过滤&lt;detailResponse&gt; 元素,然后选择具有值Active 的那些元素来获取&lt;PolicyStatusDesc&gt; 具有值Active 的元素。

使用查询语法:

var items = from el in xdoc.Descendants("detailResponse")
            where el.Descendants("PolicyStatusDesc").Any(p => p.Value == "Active")
            select el;

或者使用方法语法:

 var items = xdoc.Descendants("detailResponse")
                 .Where(el => el.Descendants("PolicyStatusDesc")
                     .Any(p => p.Value == "Active"));

【讨论】:

以上是关于Linq to XML 完整的 Child Element XL 结构的主要内容,如果未能解决你的问题,请参考以下文章

Linq学习随笔二------LINQ to XML

带有 XML 数据库字段的 Linq-to-SQL —— 为啥会这样?

C# linq to Xml(复习用)

LINQ to XML概述

LINQ to XML简介

Linq To Xml