我有以下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>aaaaaa</OrderNumber>
<ParentServiceTag nil="true" />
<ServiceTag>1234567</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>1846</OrderNumber>
<ParentServiceTag nil="true" />
<ServiceTag>8523145</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>
</GetAssetWarrantyResult>
我要做的是删除Warranty
节点中Warranties
重复XElement
的每个ServiceLevelDescription
节点。
我尝试编辑的部分示例:
<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>
</Warranties>
我尝试了几种变体:
XDocument testing = XDocument.Load(testXMLPath);
testing.Root.Element("Response").Descendants("Warranty")
.Where(x => (string)x.Element("ServiceLevelDescription") == (string)x.Element("ServiceLevelDescription"))
.Remove();
和
var testRemoval = from warranties in testing.Descendants("Request")
from warranty in warranties.Descendants()
group warranties by warranty.Attribute("Warranty").Value into distinctResult
select new
{
warr = distinctResult.FirstOrDefault().Attribute("ServiceLevelDescription").Value, value = distinctResult.Key
};
可悲的是,这不起作用。
我尝试过:This和this - 这是我想要完成的两件最接近的事情
澄清:我只是想根据Warranty
父节点中ServiceLevelDescription
字段是否重复来删除重复的(Warranties
)节点。
注意:此XML来自一个蒸汽。也许我可以在它出现时过滤它
更新:我决定尝试从另一个角度来解决这个问题。也许如果我尝试使用所需的信息重新创建xml,这将有效。
这是我到目前为止所做的:
var newDocument = new XDocument(new XElement("Machine", xlBaseInfo.Select(z =>
new XElement("Asset",
new XElement("Product", z.Product),
new XElement("OrderNumber", z.OrderNumber),
new XElement("ServiceTag", z.ServiceTag),
new XElement("ShipDate", z.ShipDate),
(new XElement("Warranties", testing.Select(x =>
new XElement("Warranty",
new XElement("Service",
new XElement("ServiceDescription", x.Service),
new XElement("Provider", x.Provider),
new XElement("StartDate", x.StartDate),
new XElement("EndDate", x.EndDate),
new XElement("Type", x.TypeOfWarranty)
)))
//Get unique results here .FirstOrDefualt Does not work
))))));
更新2:我发现了这一点,看起来很有希望:
// Return a list of duplicate nodes
var findDups = from n in testing.Root.Descendants("Warranties")
group n by n.Attribute("ServiceLevelDescription").Value into warrantyGroup
where warrantyGroup.Count() > 1
from eg in warrantyGroup
where eg.Attribute("ServiceLevelDescription").Value != "0" //TODO: <--- Condition to check for duplicates
select eg;
// Remove the duplicate nodes
foreach (XElement element in findDups)
{
element.Remove();
}
OR:
XDocument groupTest = XDocument.Load(testXMLPath);
groupTest.Root.Elements("Warranties")
.SelectMany(s => s.Elements("Warranty")
.GroupBy(g => g.Attribute("ServiceLevelDescription").Value)
.SelectMany(m => m.Skip(1))).Remove();
答案 0 :(得分:1)
我想首先说,如果你不得不做这种过滤,整体设计看起来有缺陷。在说,我不确定你在做什么的背景,所以无论如何这是一个解决方案。
这应该有用。
document.Root.DescendantsAndSelf("Warranties")
.SelectMany(n =>
n.Elements("Warranty")
.GroupBy(g => g.Element("ServiceLevelDescription").Value)
.Where(g => g.Count() > 1)
.SelectMany(g => g))
.Remove();
以下是按上述查询执行顺序排列的内容。如果你不能跟随,请随便。
<Warranties />
节点及其子节点,<Warranty />
对每个<Warranties />
节点中的<ServiceLevelDescription />
个孩子进行分组,我最初获取<Warranties />
个节点而不是<Warranty />
个节点,因为我希望将每组<Warranty />
个节点组合在一起,以便仅从其父<Warranties />
中删除重复项节点
以下是原始输入的输出:
<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>aaaaaa</OrderNumber>
<ParentServiceTag nil="true" />
<ServiceTag>1234567</ServiceTag>
<ShipDate>2014-03-21T00:00:00</ShipDate>
<Warranties>
<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>
</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>1846</OrderNumber>
<ParentServiceTag nil="true" />
<ServiceTag>8523145</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>
</Warranties>
</DellAsset>
</Response>
</GetAssetWarrantyResult>
</GetAssetWarrantyResponse>
这是你期望的吗?
答案 1 :(得分:0)
你可以尝试像遍历文档和删除所有的双重内容,我想你可以在linq中编写一个子查询,而不是每个都使用
var info=testing.Root.Element("Response").Descendants("Warranty");
foreach (var qry in info)
{
if(qry.Slect(x => (string)x.Element("ServiceLevelDescription")).Count()>1)
{
qry.Remove();
}
}