如何移除无S-C-I-I子元素的SUB-ELEMENT父元素?
问题:移除不包含S-C-I-I子元素的SUB-ELEMENT节点
原始XML数据
<root> <SUB-ELEMENT> <SHORT-NAME>SCB1</SHORT-NAME> <B-C> <S-C> <C-P-R DEST="S-A">MC_Path</C-P-R> </S-C> </B-C> <PDUS /> <S-P-R DEST="S-A">SA_Sub_Path</S-P-R> </SUB-ELEMENT> <SUB-ELEMENT> <SHORT-NAME>SCB2</SHORT-NAME> <B-C> <S-C> <C-P-R DEST="S-A">SA_Sub_Path</C-P-R> <PDUS> <S-C-I-I> <HEADER-ID>10772</HEADER-ID> </S-C-I-I> <S-C-I-I> <HEADER-ID>10773</HEADER-ID> </S-C-I-I> </PDUS> </S-C> <S-C> <C-P-R DEST="S-A">MC_Path</C-P-R> </S-C> </B-C> <PDUS> <S-C-I-I> <HEADER-ID>10774</HEADER-ID> </S-C-I-I> </PDUS> <S-P-R DEST="S-A">SA_Sub_Path</S-P-R> </SUB-ELEMENT> <SUB-ELEMENT> <SHORT-NAME>SCB3</SHORT-NAME> <B-C> <S-C> <C-P-R DEST="S-A">MC_Path</C-P-R> </S-C> </B-C> <PDUS /> <S-P-R DEST="S-A">SA_Sub_Path</S-P-R> </SUB-ELEMENT> </root>
需求
移除所有不包含<S-C-I-I>子元素的<SUB-ELEMENT>节点,最终仅保留SCB2对应的节点。
错误代码及问题分析
用户尝试的代码如下:
StringReader sr = new StringReader(xml); XDocument d = XDocument.Load(sr); d.Descendants("SUB-ELEMENT").Where(x => x.Element("S-C-I-I") == null).Remove(); d.Save(filepath);
这段代码错误移除了所有<SUB-ELEMENT>节点,核心问题是:x.Element("S-C-I-I")只会查找当前<SUB-ELEMENT>的直接子节点,但<S-C-I-I>实际嵌套在<PDUS>或<B-C>/<S-C>/<PDUS>层级下,属于后代节点而非直接子节点,因此所有<SUB-ELEMENT>都会被判定为不包含目标节点,最终全部被移除。
正确解决方案
要判断<SUB-ELEMENT>下是否存在任意层级的<S-C-I-I>节点,需使用Descendants()方法遍历所有后代元素,再判断是否存在目标节点:
StringReader sr = new StringReader(xml); XDocument d = XDocument.Load(sr); // 移除所有不包含S-C-I-I后代节点的SUB-ELEMENT d.Descendants("SUB-ELEMENT") .Where(x => !x.Descendants("S-C-I-I").Any()) .Remove(); d.Save(filepath);
这段代码会逐个检查每个<SUB-ELEMENT>的所有后代元素,仅保留包含<S-C-I-I>的节点(即SCB2对应的节点)。
内容的提问来源于stack exchange,提问作者Arun Raj
相关产品推荐
相关产品推荐

