首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于重复x元素的C# linq XDoc删除子节点

基于重复x元素的C# linq XDoc删除子节点
EN

Stack Overflow用户
提问于 2016-02-10 22:24:27
回答 2查看 463关注 0票数 0

我有以下XDocument:

代码语言:javascript
复制
<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>

我要做的是删除Warranties节点中的每个Warranties节点,该节点具有重复的ServiceLevelDescription XElement

我正在尝试编辑的部分示例:

代码语言:javascript
复制
<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>

我尝试了几种变体:

代码语言:javascript
复制
XDocument testing = XDocument.Load(testXMLPath);
testing.Root.Element("Response").Descendants("Warranty")
                .Where(x => (string)x.Element("ServiceLevelDescription") == (string)x.Element("ServiceLevelDescription"))
                .Remove();

以及:

代码语言:javascript
复制
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
                              };

可悲的是,这是行不通的。

我试过了:Thisthis --这是我最想完成的两件事

澄清:我只是想删除重复(Warranty)节点,如果ServiceLevelDescription字段是在Warranties父节点中复制的话。

注意:这个XML来自一个蒸汽。也许当它进来的时候我可以过滤它

更新:--我决定尝试从另一个角度来处理这个问题。也许,如果我尝试用所需的信息重新创建xml,这将是可行的。

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

代码语言:javascript
复制
    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:我发现了这个,看起来很有希望:

代码语言:javascript
复制
// 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();
            }

或:

代码语言:javascript
复制
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();
EN

回答 2

Stack Overflow用户

发布于 2016-02-15 09:10:44

我想说的是,如果您需要进行这种过滤,那么总体设计看起来是有缺陷的。说到这里,我不确定你在做什么,所以不管你做什么,这里都有一个解决方案。

这应该能行。

代码语言:javascript
复制
document.Root.DescendantsAndSelf("Warranties")
    .SelectMany(n =>
        n.Elements("Warranty")
            .GroupBy(g => g.Element("ServiceLevelDescription").Value)
            .Where(g => g.Count() > 1)
            .SelectMany(g => g))
    .Remove();  

下面是按上面查询执行的顺序对正在发生的事情进行的详细分析。如果你不能跟着走,问一问吧。

  1. 查找每个<Warranties />节点及其子节点,
  2. 将每个<Warranty />节点中的<Warranties />子节点按<ServiceLevelDescription />分组,
  3. 丢弃任何唯一的节点,只保留重复的
  4. 将XElements的难以置信的嵌套列表扁平化为一个IEnumerable,并在其上执行.Remove()。

首先,我获取<Warranties />节点而不是<Warranty />节点,因为我希望将每一组<Warranty />节点组合在一起,以便只从其父<Warranties />节点中删除重复的节点。

以下是原始输入的输出:

代码语言:javascript
复制
<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
EN

Stack Overflow用户

发布于 2016-02-10 22:35:31

您可以尝试像遍历文档和删除所有的“双”,我想您可以在linq中编写一个子查询,而不是为每个查询编写一个子查询。

代码语言:javascript
复制
 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();
        }
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35327173

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档