删除没有子元素的 xelement

Posted

技术标签:

【中文标题】删除没有子元素的 xelement【英文标题】:Delete an xelement with no child element 【发布时间】:2020-06-27 13:15:07 【问题描述】:

我使用 XElement 的 XML 结构如下所示。我在 XDocument 中使用 XElement

<?xml version='1.0' encoding='UTF-8'?>
<return xmlns:rmas="" xmlns:xsi="" xsi:noNamespaceSchemaLocation="">
  <header>
    [...]
  </header>
  <body>
     <scheme>
        [...]
        <data>
          <serial-no>1</serial-no>
          <employment>1</employment>
          <code>1234</code>
        </data>
        <data />
        <data />
     </scheme>
     <scheme>
        [...]
        <data>
          <serial-no>1</serial-no>
          <employment>1</employment>
          <code>1234</code>
        </data>
        <data />
        <data />
     </scheme>
     <scheme>
        [...]
        <data>
          <serial-no>1</serial-no>
          <employment>1</employment>
          <code>1234</code>
        </data>
        <data />
        <data />
     </scheme>
  </body>
</return>

我想删除所有没有子元素的数据元素,即&lt;data /&gt; 元素。这是我的代码

 foreach (XElement scheme in doc.Descendants("scheme"))
 
            //copy an existing node as template for new data node.
            XElement newData = XElement.Parse(scheme.Element("data").ToString());
            newData.Element("serial-no").SetValue("abc1234");
            newData.Element("employment").SetValue("PUZAD-452");
            newData.Element("code").SetValue(codeValue);


            XElement newData2 = XElement.Parse(scheme.Element("data").ToString());
            newData2.Element("serial-no").SetValue("abc1234");
            newData2.Element("employment").SetValue("PUZAD-452");
            newData2.Element("code").SetValue(codeValue);


            XElement newData3 = XElement.Parse(scheme.Element("data").ToString());
            newData3.Element("serial-no").SetValue("abc1234");
            newData3.Element("employment").SetValue("PUZAD-452");
            newData3.Element("code").SetValue(codeValue);

            if (getGlobalScheme1 == "1111")
            
                if ((string)(scheme.Descendants("code").First()) == "1111")
                
                    newData2.RemoveAll();
                    newData3.RemoveAll();
                
                scheme.Add(newData);
            
            if (getGlobalScheme2 == "2222")
            
                if ((string)(scheme.Descendants("code").First()) == "2222")
                
                    newData.RemoveAll();
                    newData3.RemoveAll();
                
                scheme.Add(newData2);
            

            if (getGlobalScheme3 == "3333")
            
                if ((string)(scheme.Descendants("code").Last()) == "3333")
                
                    newData.RemoveAll();
                    newData2.RemoveAll();
                
                scheme.Add(newData3);
            

我如何实现删除没有子元素的&lt;data /&gt; 元素的目标。我一直在努力解决这个问题,但无济于事。

【问题讨论】:

这能回答你的问题吗? how to remove Xelement without its children node using LINQ? 这能回答你的问题吗? How to delete specific nodes from an XElement? 尝试以下操作:列出 doc.Descendants("scheme") 中的 方案; for(int i = scheme.Count() - 1; i >= 0; i--) scheme = scheme[i]; @Lucifer 不,它没有。我只想删除没有子元素的数据元素 @hopeforall 你试过我的吗? 【参考方案1】:

我会试着回答这个问题。

尝试将具有子元素的元素添加到数组中,然后对其进行迭代。

试一试,在foreach 语句之前使用它:

    var nodes = doc.Descendants("scheme").Where(x => x.Element("data") != null).ToList();

除此之外,您可以尝试使用完全相反的逻辑,方法是检查您当前正在迭代的节点是否有子节点,代码为 sn-p:

    YourXmlNode.ChildNodes.OfType<XmlElement>().Any()

我还添加了一些文章和答案的链接,我认为这些链接可以帮助您解决问题。

XmlNode.ChildNodes Property Check whether an XML Element has child elements or a value How to delete specific nodes from an XElement?

【讨论】:

【参考方案2】:

(1) 让我们将您的 XML 保存为文件系统上的文件。

(2) 我们将创建一个 SCHEME 节点的List&lt;XElement&gt; 列表。

(3) 遍历 SCHEME 节点列表并删除没有子节点的 DATA 元素。

(4) 将修改后的 XML 保存回文件。

XML 文件

<?xml version="1.0" encoding="UTF-8"?>
<return xmlns:rmas="someURI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="fafa.xsd">
    <header>[...]</header>
    <body>
        <scheme>
            <data>
                <serial-no>1</serial-no>
                <employment>1</employment>
                <code>1234</code>
            </data>
            <data/>
            <data/>
        </scheme>
        <scheme>
            <data>
                <serial-no>1</serial-no>
                <employment>1</employment>
                <code>1234</code>
            </data>
            <data/>
            <data/>
        </scheme>
        <scheme>
            <data>
                <serial-no>1</serial-no>
                <employment>1</employment>
                <code>1234</code>
            </data>
            <data/>
            <data/>
        </scheme>
    </body>
</return>

c#

void Main()

    const string fileName = @"e:\Temp\Delete.xml";
    const string SCHEME = "scheme";
    const string DATA = "data";

    XDocument xdoc = XDocument.Load(fileName);

    // create list of SCHEME nodes
    List<XElement> nodes = xdoc.Descendants(SCHEME).ToList();

    // iterate through list of SCHEME nodes and delete DATA elements without children.
    foreach (XElement node in nodes)
        node.Elements(DATA).Where(n => n.DescendantNodes().Count() == 0).Remove();

    // end result
    Console.WriteLine(xdoc);

    // save back
//  xdoc.Save(fileName);

输出 XML

<return xmlns:rmas="someURI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="fafa.xsd">
    <header>[...]</header>
    <body>
        <scheme>
            <data>
                <serial-no>1</serial-no>
                <employment>1</employment>
                <code>1234</code>
            </data>
        </scheme>
        <scheme>
            <data>
                <serial-no>1</serial-no>
                <employment>1</employment>
                <code>1234</code>
            </data>
        </scheme>
        <scheme>
            <data>
                <serial-no>1</serial-no>
                <employment>1</employment>
                <code>1234</code>
            </data>
        </scheme>
    </body>
</return>

【讨论】:

以上是关于删除没有子元素的 xelement的主要内容,如果未能解决你的问题,请参考以下文章

对 XElement 的子节点的索引访问

如何将子元素作为解码字符串添加到 XElement?

子 XElement 的索引

XElement 的子级

在 XElement WriteTo 方法中,强制 XmlWriter 为具有已定义 xmlns 属性的子元素使用前缀

c# foreach 没有在循环中获取下一个 XElement 名称