使用Linq删除XML文档的部分

本文关键字:文档 XML Linq 删除 使用 | 更新日期: 2023-09-27 18:11:18

我如何使用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>

谢谢

使用Linq删除XML文档的部分

这将删除任何具有以括号开始和结束的子NameReceiptLayout节点,并产生您想要的输出:

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

使用let关键字的BrokenGlass代码的变体

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元素,这样一切都不会崩溃,如果没有一个:-)