【问题标题】:Remove all child nodes from the parent except one specific, an xml in c #从父节点中删除所有子节点,除了一个特定的 C# 中的 xml
【发布时间】:2018-11-16 14:22:43
【问题描述】:

这是 Xml

 <ItemWarehouseInfo>
      <row>
        <MinimalStock>0.000000</MinimalStock>
        <MaximalStock>0.000000</MaximalStock>
        <MinimalOrder>0.000000</MinimalOrder>
        <StandardAveragePrice>0.000000</StandardAveragePrice>
        <Locked>tNO</Locked>
        <WarehouseCode>Mc</WarehouseCode>
        <DefaultBinEnforced>tNO</DefaultBinEnforced>
      </row>
      ...other equal lines
    </ItemWarehouseInfo>

我必须从除 WarehouseCode 节点之外的每个行节点中删除所有子节点 我尝试了这种方法,但显然我错了,没有任何改变:

    XDocument xdoc = XmlHelper.LoadXDocFromString(xmlOITM);
XElement magaRow = xdoc.Root.Descendants(Constants.Articoli.ART_MAGA_NODES).FirstOrDefault();//ItemWarehouseInfo node
List<XElement> row = magaRow.Elements().ToList();//row node
foreach(XElement child in row.Elements())
{
    if (child.Name != "WarehouseCode")
    {
        child.Remove();
    }
}

这是我期望的最终结果:

<ItemWarehouseInfo>
      <row>
        <WarehouseCode>Mc</WarehouseCode>
      </row>
      ...other equal lines
</ItemWarehouseInfo>

【问题讨论】:

  • 只是我个人的喜好,但我会使用 Xsl 来完成这样的任务。如果你有兴趣,我会发布一个答案。

标签: c# xml linq


【解决方案1】:
doc.Descendants("row").Elements().Where(e => e.Name != "WarehouseCode").Remove();

说明:

  • doc.Descendants("row") - 查找所有行元素,无论它们有多深。

  • Elements() - 获取所有直接子元素

  • Where() - 获取名称不是WarehouseCode的所有元素

  • Remove() - 删除所有找到的元素

【讨论】:

  • 虽然此代码 sn-p 可能是解决方案,但包含解释确实有助于提高帖子的质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
  • @TânNguyễn 添加了解释?
【解决方案2】:

你不需要为每一行调用.Elements(),你已经得到了元素列表:

foreach(XElement child in row)
{
    if (child.Name != "WarehouseCode")
    {
        child.Remove();
    }
}

【讨论】:

  • @r.pezzolati,它对我有用,xdoc 已修改。您需要澄清“不起作用”的确切含义...
  • Xml 保持不变
【解决方案3】:

获取行,删除它。创建新行,添加该行的 WarehouseCode,然后将该行添加到 magaRow。如果这不起作用,我怀疑命名空间会导致问题。

XElement row = magaRow.Element("row");
row.Remove();
XElement newRow = new XElement("row");
newRow.Add(row.Element("WarehouseCode"));
magaRow.Add(newRow);

【讨论】: