C# XML 复杂查询到 XDocument

本文关键字:XDocument 查询 复杂 XML | 更新日期: 2023-09-27 18:34:19

我有一个来自'选择新'语句的复杂集合。我一直在尝试将其输出到新的"XDocument",但我无法做到。感谢您对此的任何帮助。

源示例:

<GetAssetWarrantyResponse>
  <GetAssetWarrantyResult>
    <Faults />
    <Response>
      <DellAsset>
        <AssetParts nil="true" />
        <CountryLookupCode>11</CountryLookupCode>
        <CustomerNumber>100540040</CustomerNumber>
        <IsDuplicate>false</IsDuplicate>
        <ItemClassCode>UI002</ItemClassCode>
        <LocalChannel>05</LocalChannel>
        <MachineDescription>OPTI 3020,TIGRISSFFFBTX</MachineDescription>
        <OrderNumber>584290163</OrderNumber>
        <ParentServiceTag nil="true" />
        <ServiceTag>1CZTF02</ServiceTag>
        <ShipDate>2014-03-21T00:00:00</ShipDate>
        <Warranties>
          <Warranty>
            <EndDate>2022-03-21T23:59:59</EndDate>
            <EntitlementType>INITIAL</EntitlementType>
            <ItemNumber>422-0052</ItemNumber>
            <ServiceLevelCode>D</ServiceLevelCode>
            <ServiceLevelDescription>DirectLine Service</ServiceLevelDescription>
            <ServiceLevelGroup>11</ServiceLevelGroup>
            <ServiceProvider>DELL</ServiceProvider>
            <StartDate>2014-03-21T00:00:00</StartDate>
          </Warranty>
          <Warranty>
            <EndDate>2017-03-21T23:59:59</EndDate>
            <EntitlementType>INITIAL</EntitlementType>
            <ItemNumber>984-0092</ItemNumber>
            <ServiceLevelCode>KK</ServiceLevelCode>
            <ServiceLevelDescription>Keep Your Hard Drive Service</ServiceLevelDescription>
            <ServiceLevelGroup>11</ServiceLevelGroup>
            <ServiceProvider>DELL</ServiceProvider>
            <StartDate>2014-03-21T00:00:00</StartDate>
          </Warranty>
          <Warranty>
            <EndDate>2017-03-21T23:59:59</EndDate>
            <EntitlementType>EXTENDED</EntitlementType>
            <ItemNumber>939-7358</ItemNumber>
            <ServiceLevelCode>ND</ServiceLevelCode>
            <ServiceLevelDescription>Next Business Day Support</ServiceLevelDescription>
            <ServiceLevelGroup>5</ServiceLevelGroup>
            <ServiceProvider>UNY</ServiceProvider>
            <StartDate>2015-03-22T00:00:00</StartDate>
          </Warranty>
          <Warranty>
            <EndDate>2015-03-21T23:59:59</EndDate>
            <EntitlementType>INITIAL</EntitlementType>
            <ItemNumber>939-6868</ItemNumber>
            <ServiceLevelCode>ND</ServiceLevelCode>
            <ServiceLevelDescription>Next Business Day Support</ServiceLevelDescription>
            <ServiceLevelGroup>5</ServiceLevelGroup>
            <ServiceProvider>UNY</ServiceProvider>
            <StartDate>2014-03-21T00:00:00</StartDate>
          </Warranty>
          <Warranty>
            <EndDate>2022-03-24T23:59:59</EndDate>
            <EntitlementType>INITIAL</EntitlementType>
            <ItemNumber>421-9982</ItemNumber>
            <ServiceLevelCode>D</ServiceLevelCode>
            <ServiceLevelDescription>DirectLine Service</ServiceLevelDescription>
            <ServiceLevelGroup>11</ServiceLevelGroup>
            <ServiceProvider>DELL</ServiceProvider>
            <StartDate>2014-03-21T00:00:00</StartDate>
          </Warranty>
          <Warranty>
            <EndDate>2022-03-24T23:59:59</EndDate>
            <EntitlementType>INITIAL</EntitlementType>
            <ItemNumber>525-0013</ItemNumber>
            <ServiceLevelCode>D</ServiceLevelCode>
            <ServiceLevelDescription>DirectLine Service</ServiceLevelDescription>
            <ServiceLevelGroup>11</ServiceLevelGroup>
            <ServiceProvider>DELL</ServiceProvider>
            <StartDate>2014-03-21T00:00:00</StartDate>
          </Warranty>
          <Warranty>
            <EndDate>2022-03-24T23:59:59</EndDate>
            <EntitlementType>INITIAL</EntitlementType>
            <ItemNumber>422-0008</ItemNumber>
            <ServiceLevelCode>D</ServiceLevelCode>
            <ServiceLevelDescription>DirectLine Service</ServiceLevelDescription>
            <ServiceLevelGroup>11</ServiceLevelGroup>
            <ServiceProvider>DELL</ServiceProvider>
            <StartDate>2014-03-21T00:00:00</StartDate>
          </Warranty>
        </Warranties>
      </DellAsset>
      <DellAsset>
        <AssetParts nil="true" />
        <CountryLookupCode>11</CountryLookupCode>
        <CustomerNumber>100540040</CustomerNumber>
        <IsDuplicate>false</IsDuplicate>
        <ItemClassCode>7M002</ItemClassCode>
        <LocalChannel>05</LocalChannel>
        <MachineDescription>POWEREDGE R720XD, ORCA S PE</MachineDescription>
        <OrderNumber>339791846</OrderNumber>
        <ParentServiceTag nil="true" />
        <ServiceTag>1VF0TW1</ServiceTag>
        <ShipDate>2013-03-20T00:00:00</ShipDate>
        <Warranties>
          <Warranty>
            <EndDate>2016-03-20T23:59:59</EndDate>
            <EntitlementType>INITIAL</EntitlementType>
            <ItemNumber>936-7263</ItemNumber>
            <ServiceLevelCode>SV</ServiceLevelCode>
            <ServiceLevelDescription>Silver Premium Support</ServiceLevelDescription>
            <ServiceLevelGroup>8</ServiceLevelGroup>
            <ServiceProvider>DELL</ServiceProvider>
            <StartDate>2013-03-20T00:00:00</StartDate>
          </Warranty>
          <Warranty>
            <EndDate>2016-03-20T23:59:59</EndDate>
            <EntitlementType>INITIAL</EntitlementType>
            <ItemNumber>983-6402</ItemNumber>
            <ServiceLevelCode>KK</ServiceLevelCode>
            <ServiceLevelDescription>Keep Your Hard Drive Service</ServiceLevelDescription>
            <ServiceLevelGroup>11</ServiceLevelGroup>
            <ServiceProvider>DELL</ServiceProvider>
            <StartDate>2013-03-20T00:00:00</StartDate>
          </Warranty>
          <Warranty>
            <EndDate>2016-03-20T23:59:59</EndDate>
            <EntitlementType>EXTENDED</EntitlementType>
            <ItemNumber>936-7243</ItemNumber>
            <ServiceLevelCode>ND</ServiceLevelCode>
            <ServiceLevelDescription>Next Business Day Support</ServiceLevelDescription>
            <ServiceLevelGroup>5</ServiceLevelGroup>
            <ServiceProvider>UNY</ServiceProvider>
            <StartDate>2014-03-21T00:00:00</StartDate>
          </Warranty>
          <Warranty>
            <EndDate>2014-03-20T23:59:59</EndDate>
            <EntitlementType>INITIAL</EntitlementType>
            <ItemNumber>989-2701</ItemNumber>
            <ServiceLevelCode>ND</ServiceLevelCode>
            <ServiceLevelDescription>Next Business Day Support</ServiceLevelDescription>
            <ServiceLevelGroup>5</ServiceLevelGroup>
            <ServiceProvider>UNY</ServiceProvider>
            <StartDate>2013-03-20T00:00:00</StartDate>
          </Warranty>
        </Warranties>
      </DellAsset>
      </Response>
    </GetAssetWarrantyResult>
</GetAssetWarrantyResponse>

这是我到目前为止所拥有的:

    var xlQueryTest = (from mainRequest in testing.Descendants("Response")
                  select new
                  {
                      Baseinfo = (from baseInfo in mainRequest.Descendants("DellAsset")
                                  select new
                                  {
                                      MachineName = baseInfo.Element("MachineDescription").Value,
                                      ServiceTag = baseInfo.Element("ServiceTag").Value,
                                      WarrantyStart = baseInfo.Element("ShipDate").Value,
                                      Warranties = (from warranty in baseInfo.Descendants("Warranties")
                                                    select new
                                                    {
                                                        Service = (string)warranty.Element("ServiceLevelDescription").Value,
                                                        Provider = (string)warranty.Element("ServiceProvider").Value,
                                                        StartDate = (string)warranty.Element("StartDate").Value,
                                                        EndDate = (string)warranty.Element("EndDate").Value,
                                                        TypeOfWarranty = (string)warranty.Element("EntitlementType").Value
                                                    }).GroupBy(x => x.Service)
                                  }).AsEnumerable().ToList()
                  });
var newDocument = new XDocument(new XElement("Request",
    xlQueryTest.Select(a => a.Baseinfo).Select( 
        //HOWTO
        //iterate through "BaseInfo" Elements
        //iterate through "Warranties" Collection 

我在访问馆藏时遇到困难

我试图实现的结果是:

<Request>
    <BaseInfo>
        <MachineName>a</MachineName>
        <ServiceTag>a12345</ServiceTag>
        <ShipDate>01/01/2000</ShipDate>
            <Warranties>
                <Warranty>
                    <ServiceLevelDescription>dfdlkfj</ServiceLevelDescription>
                    <ServiceProvider>ABC</ServiceProvider>
                    <StartDate>01/01/2001</StartDate>
                    <EndDate>01/05/2007</EndDate>
                </Warranty>
                <Warranty>
                </Warranty>
            </Warranties>
    </BaseInfo>
    <BaseInfo>
        <MachineName>b</MachineName>
        <ServiceTag>b12345</ServiceTag>
        <ShipDate>01/01/2010</ShipDate>
            <Warranties>
                <Warranty>
                    <ServiceLevelDescription>dfdlkfj</ServiceLevelDescription>
                    <ServiceProvider>ABCF</ServiceProvider>
                    <StartDate>01/01/2011</StartDate>
                    <EndDate>01/05/2017</EndDate>
                </Warranty>
                <Warranty>
                </Warranty>
            </Warranties>
    </BaseInfo>
</Request>

更新:我把这个放在一起,试图进一步解释我正在尝试做什么。

我怎样才能将其转换为"新的XDocument"以获得所需的结果(上图)

foreach(var request in xlQueryTest)
            {
                //<Request>
                foreach(var machine in request.Baseinfo)
                {
                    //<BaseInfo>
                        //<MachineName>machine.MachineName</MachineName>
                        //<ServiceTag>machine.ServiceTag</ServiceTag>
                        //<ShipDate>machine.WarrantyStart</ShipDate>
                        //  <Warranites>
                        foreach(var warranty in machine.Warranties)
                        {
                            //<Warranty>
                                //<ServiceLevelDescription>warranty.Service</ServiceLevelDescription>
                                //<ServiceProvider>warranty.Provier</ServiceProvider>
                                //<StartDate>warranty.StartDate</StartDate>
                                //<EndDate>warranty.EndDate</EndDate>
                            //</Warranty>
                        }
                        //  </Warranties>
                    }
                    //</BaseInfo>
                }
                //</Request>
            }

答:我选择了har07的答案,因为它解决了重复的问题。Jdweng的解决方案很优雅,但没有纠正重复的信息。

var xlQueryTest = (from mainRequest in testing.Descendants("Response")
                               select new
                               {
                                   Baseinfo = (from baseInfo in mainRequest.Descendants("DellAsset")
                                               select new
                                               {
                                                   MachineName = baseInfo.Element("MachineDescription").Value,
                                                   ServiceTag = baseInfo.Element("ServiceTag").Value,
                                                   WarrantyStart = baseInfo.Element("ShipDate").Value,
                                                   Warranties = (from warranty in baseInfo.Descendants("Warranty")
                                                                 select new
                                                                 {
                                                                     Service = (string)warranty.Element("ServiceLevelDescription"),
                                                                     Provider = (string)warranty.Element("ServiceProvider"),
                                                                     StartDate = (string)warranty.Element("StartDate"),
                                                                     EndDate = (string)warranty.Element("EndDate"),
                                                                     TypeOfWarranty = (string)warranty.Element("EntitlementType")
                                                                 }).GroupBy(x => x.Service)
                                               }).AsEnumerable().ToList()
                               });
                        var newDocument =
                            new XDocument(new XElement("Request",
                            from t in xlQueryTest
                            from q in t.Baseinfo
                            select
                            new XElement("BaseInfo",
                                new XElement("MachineDescription", q.MachineName),
                                new XElement("ServiceTag", q.ServiceTag),
                                new XElement("ShipDate", q.WarrantyStart),
                                new XElement("Warranites",
                                from g in q.Warranties
                                select
                                    new XElement("Warranty",
                                    new XElement("ServiceLevelDescription", g.Key),
                                    new XElement("ServiceProvider", g.First().Provider),
                                    new XElement("StartDate", g.First().StartDate),
                                    new XElement("EndDate", g.First().EndDate)
                                )
                            )
                        )
                    ));

谢谢大家的帮助。

C# XML 复杂查询到 XDocument

假设您希望在输出 XML 中扩展来自Baseinfo.Warranties的分组保证,这是一种可能的方法:

var newDocument =
        new XDocument(new XElement("Request",
            from query in xlQueryTest
            from baseInfo in query.Baseinfo
            select
            new XElement("BaseInfo",
                new XElement("MachineDescription", baseInfo.MachineName),
                new XElement("ServiceTag", baseInfo.ServiceTag),
                new XElement("ShipDate", baseInfo.WarrantyStart),
                new XElement("Warranites",
                    from grp in baseInfo.Warranties
                    from warranty in grp
                    select
                    new XElement("Warranty",
                        new XElement("ServiceLevelDescription", warranty.Service),
                        new XElement("ServiceProvider", warranty.Provider),
                        new XElement("StartDate", warranty.StartDate),
                        new XElement("EndDate", warranty.EndDate)
                    )
                )
            )
        ));

dotnetfiddle demo

如果希望将分组项目输出为一个元素,例如仅显示当前组的第一项的值,请将元素部分的创建修改为如下所示<Warranites>

new XElement("Warranites",
    from g in q.Warranties
    select
    new XElement("Warranty",
        new XElement("ServiceLevelDescription", g.Key),
        new XElement("ServiceProvider", g.First().Provider),
        new XElement("StartDate", g.First().StartDate),
        new XElement("EndDate", g.First().EndDate)
    )
)

试试这个

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication77
{
    class Program
    {
        const string FILENAME = @"C:'temp'test.xml";
        static void Main(string[] args)
        {
            string xml =
            "<Request>" +
            "</Request>";
            XDocument newDoc = XDocument.Parse(xml);
            XElement request = newDoc.Descendants("Request").FirstOrDefault();
            XDocument oldDoc = XDocument.Load(FILENAME);
            foreach (XElement dellAsset in oldDoc.Descendants("DellAsset"))
            {
                XElement baseInfo = new XElement("BaseInfo");
                request.Add(baseInfo);
                baseInfo.Add(dellAsset.Element("MachineDescription"));
                baseInfo.Add(dellAsset.Element("ParentServiceTag"));
                baseInfo.Add(dellAsset.Element("ShipDate"));
                XElement warranties = new XElement("Warranties");
                baseInfo.Add(warranties);
                XElement latestWarranty = dellAsset.Descendants("Warranty")
                    .OrderBy(x => (DateTime)x.Element("EndDate")).LastOrDefault();
                warranties.Add( new XElement("Warranty", new XElement[] {
                              latestWarranty.Element("ServiceLevelDescription"),
                              latestWarranty.Element("ServiceProvider"),
                              latestWarranty.Element("StartDate"),
                              latestWarranty.Element("EndDate"),
                              latestWarranty.Element("EntitlementType")
                }));
            }
        }
    }
}