C#XML复杂查询到XDocument

时间:2016-02-12 16:23:00

标签: c# xml linq

我有一个复杂的收藏来自一个新的'声明。我一直试图将它输出到一个新的' 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&#39;为了得到理想的结果(上图)

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

谢谢大家的帮助。

2 个答案:

答案 0 :(得分:1)

试试这个

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")
                }));

            }

        }
    }
}

答案 1 :(得分:1)

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

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