使用C#删除没有XML属性的空元素?

时间:2015-04-07 17:55:40

标签: c# xml linq

基于StackOverflow的先前答案,我使用以下语句删除所有空元素(具有属性的元素除外):

XDocument xdoc = XDocument.Parse(xmlString);

xdoc.Descendants()
    .Where(e => !e.HasAttributes && (e.IsEmpty || String.IsNullOrWhiteSpace(e.Value)))
    .Remove();

针对以下XML运行时:

<MESSAGE>
    <RELATIONSHIPS1>
        <RELATIONSHIP1 from="10017" to="1"/>
    </RELATIONSHIPS1>
    <RELATIONSHIPS2>
        <RELATIONSHIP2 from="10017" to="1"></RELATIONSHIP2>
    </RELATIONSHIPS2>
    <RELATIONSHIPS3>
        <RELATIONSHIP3 from="10017" to="1">test</RELATIONSHIP3>
    </RELATIONSHIPS3>
    <RELATIONSHIPS4 attr="test">
        <RELATIONSHIP4 from="10017" to="1"></RELATIONSHIP4>
    </RELATIONSHIPS4>
    <EXTENSION a1="1" a2="2"/>
    <FLOOD>
        <FLOOD_RESPONSE>
            <PROPERTY>
                <PROPERTY_DETAIL/>
                <PROPERTY_DETAIL></PROPERTY_DETAIL>
             </PROPERTY>
        </FLOOD_RESPONSE>
    </FLOOD>
</MESSAGE>

我期待以下内容:

<MESSAGE>
    <RELATIONSHIPS1>
        <RELATIONSHIP1 from="10017" to="1"/>
    </RELATIONSHIPS1>
    <RELATIONSHIPS2>
        <RELATIONSHIP2 from="10017" to="1"></RELATIONSHIP2>
    </RELATIONSHIPS2>
    <RELATIONSHIPS3>
        <RELATIONSHIP3 from="10017" to="1">test</RELATIONSHIP3>
    </RELATIONSHIPS3>
    <RELATIONSHIPS4 attr="test">
        <RELATIONSHIP4 from="10017" to="1"></RELATIONSHIP4>
    </RELATIONSHIPS4>
    <EXTENSION a1="1" a2="2" />
</MESSAGE>

但收到以下内容:

<MESSAGE>
  <RELATIONSHIPS3>
    <RELATIONSHIP3 from="10017" to="1">test</RELATIONSHIP3>
  </RELATIONSHIPS3>
  <RELATIONSHIPS4 attr="test">
    <RELATIONSHIP4 from="10017" to="1"></RELATIONSHIP4>
  </RELATIONSHIPS4>
  <EXTENSION a1="1" a2="2" />
</MESSAGE>

有关带有属性的嵌套空元素的任何想法都被删除了吗?

1 个答案:

答案 0 :(得分:3)

检查XElement.Value on MSDN的说明:

  

获取或设置此元素的连接文本内容。

这意味着只返回内部元素的值(仅元素,而不是属性)。例如,在您的XML中,您有这个元素:

<RELATIONSHIPS1>
    <RELATIONSHIP1 from="10017" to="1"/>
</RELATIONSHIPS1>

此元素的e.Value为空字符串,因此将删除此元素。

您可以运行此类查询以删除不需要的元素。基本上你需要检查元素,它们具有空值并且没有任何属性,并且所有它的后代都有空值而没有属性:

xdoc.Descendants()
    .Where(e => !e.HasAttributes && 
                string.IsNullOrEmpty(e.Value) &&
                e.Descendants().All(f=>String.IsNullOrEmpty(f.Value) && !f.HasAttributes))
    .Remove();