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)
)
)
)
));
谢谢大家的帮助。
假设您希望在输出 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")
}));
}
}
}
}