Reputation:
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
Upvotes: 0
Views: 2714
Reputation: 89285
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();
Upvotes: 2