简体   繁体   English

使用Linq删除XML文档的各个部分

[英]remove sections of XML document with Linq

How would i using Linq remove all section where their element contains parameter with {} ? 我如何使用Linq删除其元素包含{}参数的所有部分? In my example i want to remove section with {SecName1} 在我的示例中,我想删除{SecName1}部分

Source document: 来源文件:

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

Wanted output 想要输出

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

thanks 谢谢

This removes any ReceiptLayout node which has a child Name that starts and ends with brackets and produces your desired output: 这将删除任何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();

This can be shortened into one Linq statement, personally I prefer to keep Linq query and modification (removal) separate though: 这可以简化为一个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();

A variant of BrokenGlass code using the let keyword 使用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();

This is "premature optimization" :-) I "cache" the p.Element("Name").Value . 这是“过早优化”:-)我“缓存” p.Element("Name").Value Ah... And I check if really there is a Name Element so that everything doesn't crash if there isn't one :-) 啊......我检查是否确实有一个Name元素,这样如果没有一个,一切都不会崩溃:-)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM