0

I have one xml file with a collection of cars. I want to remove a element A and B if the car is green :

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Cars>
    <Car>
        <Color>Green</Color>
        <A>Value</A>
        <B>Value</B>
    </Car>
    <Car>
        <Color>Blue</Color>
        <A>Value</A>
        <B>Value</B>
    </Car>
    <Car>
        <Color>Yellow</Color>
        <A>Value</A>
        <B>Value</B>
    </Car>
</Cars>

I do :

XDocument.Root.Descendants("Car").Where(x => x.Element("Color").Value == "Green"). Select(x => x.Element("A")).Remove();

XDocument.Root.Descendants("Car").Where(x => x.Element("Color").Value == "Green"). Select(x => x.Element("B")).Remove();

It's work but how to do this in one line ? How to select two elements in Select ?

Thank's

2
  • Sample xml data and expected output would be helpful. The only way to achieve that is to projecting only these elements you want to get as an output. Commented Jul 6, 2016 at 8:01
  • Yes I have add my xml Commented Jul 6, 2016 at 8:36

1 Answer 1

2

This is one possible way, find Color element where value equals 'Green', grab all the following sibling elements using ElementsAfterSelf(), flatten them using SelectMany(), and finally remove them :

XDocument.Root
         .Descendants("Car")
         .Elements("Color")
         .Where(c => c.Value == "Green")
         .SelectMany(c => c.ElementsAfterSelf())
         .Remove();

UPDATE :

If the target elements strictly need to be identified by name e.g not necessarily all elements after <Color>, you can use Where() method as follow :

XDocument.Root
         .Descendants("Car")
         .Where(c => (string)c.Element("Color") == "Green")
         .SelectMany(c => c.Elements()
                           .Where(e => e.Name.LocalName == "A" ||
                                       e.Name.LocalName == "B"))
         .Remove();

If list of target element names may grow to more than 2 ("A" and "B"), I'd suggest to use array and Contains() for filtering :

var targetElementNames = new[]{ "A", "B", "C" };
XDocument.Root
         .Descendants("Car")
         .Where(c => (string)c.Element("Color") == "Green")
         .SelectMany(c => c.Elements()
                           .Where(e => targetElementNames.Contains(e.Name.LocalName))
         .Remove();
Sign up to request clarification or add additional context in comments.

2 Comments

Great! I hope that it's exactly what OP needs, because i'm pretty sure he wants to get only Car nodes which Color is green and return list of Car nodes that contain only Color subnode.
Yes but I want not remove all elements after self

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.