2016-07-06 2 views
0

У меня есть один xml-файл с коллекцией автомобилей. Я хочу, чтобы удалить элемент A и B, если автомобиль зеленый:Linq to XML - выбор нескольких элементов

<?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> 

я:

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(); 

Это работа, но как сделать это в одной строке? Как выбрать два элемента в Select?

Спасибо-х

+0

Пример данных XML и ожидаемого результата будет полезен. Единственный способ добиться этого - проецировать только те элементы, которые вы хотите получить в качестве вывода. –

+0

Да, я добавил свой xml –

ответ

2

Это один из возможных способов, найти Color элемент, где значение равно «Green», захватить все следующие одноуровневые элементы, используя ElementsAfterSelf(), распрямите их с помощью SelectMany(), и, наконец, удалить их:

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

ОБНОВЛЕНИЕ:

Если целевые элементы строго необходимо идентифицировать по имени, например, не обязательно все el ements после <Color>, вы можете использовать Where() метод следующим образом:

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(); 

Если список имен целевых элементов может вырасти более чем на 2 («A» и «B»), я предложил бы использовать массив и Contains() для фильтрации:

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(); 
+0

Отлично! Я надеюсь, что это именно то, что нужно OP, потому что я уверен, что он хочет получить только узлы «Car», для которых «Цвет» зеленый, и возвращает список узлов «Car», которые содержат только поднабор «Цвет». –

+0

Да, но я не хочу удалять все элементы после себя –

+0

@ Azerty123 проверить ** ОБНОВЛЕНИЕ ** раздел .. – har07

Смежные вопросы