简体   繁体   中英

Query XML with LINQ to return child elements that are different

Consider the following two XML documents..

Original

<Stock>
   <Vehicle id="123456">
      <Name>Ford Ka</Name>
      <Images>
         <Image Id="111111" Url="http://somewhere.com/GetImage.aspx?ImageId=111111" LastModified="2016-05-12 13:09:00"/>
         <Image Id="222222" Url="http://somewhere.com/GetImage.aspx?ImageId=222222" LastModified="2016-05-12 13:09:00"/>
      </Images>
   </Vehicle>
</Stock>

New

<Stock>
   <Vehicle id="123456">
      <Name>Ford Ka</Name>
      <Images>
         <Image Id="111111" Url="http://somewhere.com/GetImage.aspx?ImageId=111111" LastModified="2016-05-12 13:09:00"/>
         <Image Id="222222" Url="http://somewhere.com/GetImage.aspx?ImageId=222222" LastModified="2016-05-13 09:00:00"/>
         <Image Id="333333" Url="http://somewhere.com/GetImage.aspx?ImageId=333333" LastModified="2016-05-12 13:09:00"/>
      </Images>
   </Vehicle>
</Stock>

So the differences between them are...

  1. New XML Image Id="222222" has changed LastModified value.
  2. New XML contains a new <Image> with id="333333" .

How can I use LINQ to return an XDocument that contains the <Vehicle id> and each <Image> where the <Image id> value in the new XML is not in the original XML (difference 2) OR the <Image id> IS in the original XML BUT any of the <Image> attribute values are different to those that in the original XML for the same Image (difference 1)?

The resulting XDocument should look something like this...

<Stock>
   <Vehicle id="123456">
      <Images>
         <Image Id="222222" Url="http://somewhere.com/GetImage.aspx?ImageId=222222" LastModified="2016-05-13 09:00:00"/>
         <Image Id="333333" Url="http://somewhere.com/GetImage.aspx?ImageId=333333" LastModified="2016-05-12 13:09:00"/>
      </Images>
   </Vehicle>
</Stock>

1] join old and new vehicles by id attribute

2] find new or modified Image s, comparing them by their string representation

3] select Image s into a new Vehicle element

4] built resulting Stock from Vehicle elements

var diff = from newVehicle in newXml.Descendants("Vehicle")
           join oldVehicle in oldXml.Descendants("Vehicle")
           on     newVehicle.Attribute("id").Value 
           equals oldVehicle.Attribute("id").Value 

           select new XElement("Vehicle", newVehicle.Attribute("id"),
                                new XElement("Images",
                                         newVehicle.Descendants("Image")
                                                   .Where(i=>!oldVehicle.Descendants("Image")
                                                                       .Any(iold=>iold.ToString() == i.ToString())
                                                          )
                                             )
                               );

var stock = new XElement("Stock", diff);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM