Поиск значения во всех дочерних узлах узла XML и удаление родительского узла

#c# #xml #linq

#c# #xml #linq

Вопрос:

Попытка использовать

 exportDoc.Root.Elements("string").Where(node => !(node.Element("product").HasElements) || node.Element("product").Element("type").Value != product).Remove();
 

чтобы удалить узлы в моем XML-документе, где product строка, которую я ищу, не встречается. Вот пример моей структуры XML:

 <root>
   <string id = "Hithere">
      <product>
         <type>orange</type>
         <type>yellow</type>
         <type>green</type>
      <product>
      <element2/>
      <element3/>
    </string>
    <string id ="...">
     ...
     ... 
</root>
 

Поэтому мне нужно заглянуть под product элемент каждого string элемента И в каждый из type элементов в нем, чтобы увидеть, встречается ли значение string product (ввод в метод, в котором оно содержится). В настоящее время похоже, что мой код удаляет узел только в том случае, если product строка, которую я ищу, соответствует значению только первого type элемента.

Весь смысл в том, чтобы удалить все строковые узлы из этого xdoc, у которых нет продукта, который я ищу, в списке под их product элементом.

Ответ №1:

Вам нужно немного изменить условие поиска:

 var nodesToRemove = xDoc.Root
    .Elements("string")
    .Where(node =>
        !(node.Element("product").HasElements) ||
        node.Element("product").Elements("type").All(x => x.Value != product))
    .ToList();
 

Это должно соответствовать элементам, все типы string:product: отличаются от product value (или, другими словами, если хотя бы один <type> будет соответствовать вашему product , он не будет помечен для удаления).

Комментарии:

1. Именно то, что я искал. Спасибо!

Ответ №2:

Вы не можете удалить (), пока вы все еще перечисляете (отложенное выполнение).

Вам нужно что-то более похожее:

 // untested
var toRemove = exportDoc.Root.Elements("string")
    .Where(node => !(node.Element("product").HasElements) ||
           node.Element("product").Element("type").Value != product).ToList();
toRemove.Remove();
 

Комментарии:

1. Спасибо за ответ. Я думаю, проблема в том, что .Element("type") возвращается только первый type элемент. Итак, если там есть только один тип продукта, это работает, но если существует несколько типов продуктов, в частности те, которые встречаются перед ним в XML, тогда это не сработает.