You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用LINQ移除XML中属性值非Word的Target类型feature元素?

问题:移除XML中不符合条件的Target元素

原始XML文档

<?xml version="1.0"?>
<report>
    <feature tag="Config"/>
    <feature tag="Runtime">
        <feature tag="Output">
            <feature tag="Target">
                <property name="type" value="Html"/>
                <property name="driver" value="Telelogic.Html.Driver"/>
            </feature>
            <feature tag="Target">
                <property name="type" value="Word"/>
                <property name="driver" value="Telelogic.Word.Driver"/>
            </feature>
            <feature tag="Target">
                <property name="type" value="PDF"/>
                <property name="driver" value="Telelogic.Pdf.Driver"/>
            </feature>
        </feature>
    </feature>
</report>

期望处理结果

只保留type属性值为Word的Target元素,其余不符合条件的全部移除:

<?xml version="1.0"?>
<report>
    <feature tag="Config"/>
    <feature tag="Runtime">
        <feature tag="Output">
            <feature tag="Target">
                <property name="type" value="Word"/>
                <property name="driver" value="Telelogic.Word.Driver"/>
            </feature>
        </feature>
    </feature>
</report>

原代码及问题

原VB.NET代码尝试实现需求,但错误地移除了所有Target元素,导致Output节点为空:

Public Function removeElements(ByVal source As String) As Boolean
    Try
        Dim doc As New XDocument

        Dim output As String =
        "/report/feature[@tag='Runtime']/feature[@tag='Output']"

        Dim propertyType As String =
        "/report/feature[@tag='Runtime']/feature[@tag='Output']/feature[@tag='Target']/property[@name='type']"

        Dim path As String = "c:\temp\mySource.xml"

        doc = XDocument.Parse(source)
        doc.XPathSelectElements(output).Elements _
        .Where(Function(x) x.XPathSelectElement(propertyType).Attribute("value").Value <> "Word").Remove

        doc.Save(path)

        Return True

    Catch ex As Exception
        Return False
    End Try
End Function

问题根源:propertyType用了绝对XPath路径,导致每个Target元素都会去匹配整个文档中第一个type属性(值为Html),所有Target都被判定为不符合条件并删除。

修正后的解决方案

方法1:使用相对XPath路径

把propertyType改成相对当前Target元素的路径,直接查找子节点的property:

Public Function removeElements(ByVal source As String) As Boolean
    Try
        Dim doc As New XDocument
        Dim path As String = "c:\temp\mySource.xml"

        doc = XDocument.Parse(source)
        ' 直接定位到所有Target元素
        doc.XPathSelectElements("/report/feature[@tag='Runtime']/feature[@tag='Output']/feature[@tag='Target']") _
           .Where(Function(target) 
                     ' 用相对路径找当前Target下的type属性
                     target.XPathSelectElement("property[@name='type']").Attribute("value").Value <> "Word"
                  ).Remove()

        doc.Save(path)
        Return True
    Catch ex As Exception
        Return False
    End Try
End Function

方法2:纯LINQ to XML写法(更直观)

完全用LINQ语法筛选元素,避免XPath路径错误:

Public Function removeElements(ByVal source As String) As Boolean
    Try
        Dim doc As XDocument = XDocument.Parse(source)
        Dim path As String = "c:\temp\mySource.xml"

        ' 找到Output节点下的所有Target元素
        Dim targetElements = doc.Descendants("feature") _
                               .Where(Function(f) f.Attribute("tag")?.Value = "Output") _
                               .Elements("feature") _
                               .Where(Function(t) t.Attribute("tag")?.Value = "Target")

        ' 筛选出type不等于Word的元素并删除
        targetElements.Where(Function(t) 
                               t.Elements("property") _
                                .Any(Function(p) p.Attribute("name")?.Value = "type" AndAlso p.Attribute("value")?.Value <> "Word")
                            ).Remove()

        doc.Save(path)
        Return True
    Catch ex As Exception
        Return False
    End Try
End Function

两种方法都能精准筛选出需要删除的Target元素,只保留type=Word的节点。

内容的提问来源于stack exchange,提问作者Manfred Singer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 00:32:46