Удалить разделы XML-документа с помощью Linq

Как бы я с помощью Linq удалить все разделы, где их элемент содержит параметр с {}? В моем примере я хочу удалить раздел с {SecName1}

Исходный документ:

<ReceiptLayoutMaintenanceRequest>
  <ReceiptLayoutName>Test Layout1</ReceiptLayoutName> 
  <ActionName>Add</ActionName> 
 <ReceiptLayoutForMaintenance>
  <Name>Test Layout1</Name> 
  <Description>ReciptDesc</Description> 
  <PrinterName>Emulator - Receipt</PrinterName> 
  <ReceiptLayout>
    <Name>AAA</Name> 
    <Description>$</Description> 
    <TemplateName>DefaultTemplate</TemplateName> 
    <LayoutParameters /> 
  </ReceiptLayout>
  <ReceiptLayout>
    <Name>{SecName1}</Name> 
    <Description>$</Description> 
    <TemplateName>DefaultTemplate</TemplateName> 
    <LayoutParameters /> 
  </ReceiptLayout>
 </ReceiptLayoutForMaintenance>
</ReceiptLayoutMaintenanceRequest>

Требуемый вывод

<ReceiptLayoutMaintenanceRequest>
  <ReceiptLayoutName>Test Layout1</ReceiptLayoutName> 
  <ActionName>Add</ActionName> 
 <ReceiptLayoutForMaintenance>
  <Name>AAA</Name> 
  <Description>ReciptDesc</Description> 
  <PrinterName>Emulator - Receipt</PrinterName> 
  <ReceiptLayout>
    <Name>AAA</Name> 
    <Description>$</Description> 
    <TemplateName>DefaultTemplate</TemplateName> 
    <LayoutParameters /> 
  </ReceiptLayout>
 </ReceiptLayoutForMaintenance>

Спасибо

3 ответа

Это удаляет любые ReceiptLayout узел, у которого есть ребенок Name который начинается и заканчивается скобками и выдает желаемый результат:

XDocument doc = XDocument.Load(@"test.xml"); //load xml
var nodesToRemove = doc.Descendants("ReceiptLayout")
                       .Where(x => x.Element("Name").Value.StartsWith("{") 
                                && x.Element("Name").Value.EndsWith("}"))
                       .ToList();

foreach (var node in nodesToRemove)
    node.Remove();

Это можно сократить до одного оператора Linq, лично я предпочитаю разделять запрос и изменение (удаление) Linq:

doc.Descendants("ReceiptLayout")
   .Where(x => x.Element("Name").Value.StartsWith("{") 
            && x.Element("Name").Value.EndsWith("}"))
   .Remove();
var doc =  XDocument.Parse(xml);
doc.Descendants()
   .Where(n => !n.HasElements  && Regex.IsMatch(n.Value, "[{].*?[}]"))
   .Select(n=>n.Parent) // because you want to remove the section not the node
   .Remove();
xml = doc.ToString();

Вариант кода BrokenGlass с использованием let ключевое слово

var doc = XDocument.Load(@"test.xml");

var list = from p in doc.Descendants("ReceiptLayout")
           let q = p.Element("Name")
           let r = q != null ? q.Value : string.Empty
           where r.StartsWith("{") && r.EndsWith("}")
           select p;

list.Remove();

Это "преждевременная оптимизация":-) Я "кеширую" p.Element("Name").Value, Ах... И я проверяю, действительно ли Name Элемент, чтобы все не рухнуло, если его нет:-)

Другие вопросы по тегам