Linq to XML полная структура дочернего элемента XL - PullRequest
0 голосов
/ 07 ноября 2019

Я пытаюсь не использовать старый способ чтения xml и попробовать linq to xml, но мне трудно выполнить следующее:

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

С помощью этого кода я могу читать элемент bot DetailReponse, но я хочу сохранить только структуру XML detailResponseс <PolicyStatusDesc></PolicyStatusDesc>, равным Актив. Это возможно. Мне удается собирать конкретные данные на основе имен элементов, но как сохранить всю структуру дочерних элементов XML (элемент detailResponse и его дочерние элементы) с помощью Linq to XML.

Спасибо

Ответы [ 3 ]

1 голос
/ 07 ноября 2019

В вашем примере XML есть недействительный тег </out2:getPolicySummaryResponse>, который я удалил

Вот код, который вы можете использовать для вашего результата

 IEnumerable<XElement> items =
            from el in xdoc.Descendants("detailResponse")
            where  el.Element("policy")?.Element("policySummaryInfo")?.Element("PolicyStatusDesc")?.Value == "Active"
            select el;
1 голос
/ 07 ноября 2019

Я часто использую код, подобный приведенному ниже, который дает более полные результаты, чем при использовании сериализации:

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();
        }
    }
}
1 голос
/ 07 ноября 2019

Вы можете получить элементы, где <PolicyStatusDesc> имеет значение Active, отфильтровав элементы <detailResponse> с помощью el.Descendants("PolicyStatusDesc"), а затем выбрав элементы, имеющие значение 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"));
...