【问题标题】:Remove XML Node/Element by Value from another Element in same level从同一级别的另一个元素中按值删除 XML 节点/元素
【发布时间】:2016-11-02 12:33:48
【问题描述】:

正如我在线程标题中已经提到的,我想删除一个节点或元素,这取决于同一级别的另一个元素的值。

为了防止重复标签,问题不是从xml中删除一个元素或节点,而是从同一子节点/级别的另一个元素中删除节点或元素的值依赖。

为了描述这一点,我用随机样本数据构建了一个示例结构。

<ROOT>
    <DETAILS>
        <ALLOC>
            <TYPE>NEEDED</TYPE>
            <VALUE>do not remove</VALUE>
            <NAME>also requiered</NAME>
        </ALLOC>
    </DETAILS>
    <DETAILS>
        <ALLOC>
            <TYPE>UNNEEDED</TYPE>
            <VALUE>remove this</VALUE>
            <NAME> but this requiered</NAME>
        </ALLOC>
    </DETAILS>
    <DETAILS>
        <ALLOC>
            <TYPE>NEEDED</TYPE>
            <VALUE>do not remove</VALUE>
            <NAME>also requiered</NAME>
        </ALLOC>
    </DETAILS>
    <SOMEWHERE>
        <OTHERWHERE>
            <TYPE>UNNEEDED</TYPE>
            <VALUE>but do not remove</VALUE>
            <NAME>also requiered</NAME>
        </OTHERWHERE>
    </SOMEWHERE>
</ROOT>

现在我需要一个 xsl 转换来删除节点 VALUE 如果同一节点中的类型文本值是“UNNEEDED”。

这个转换的 inpur 参数看起来像这样 如果:/ROOT/DETAILS/ALLOC/TYPE=UNNEEDED 然后删除:/ROOT/DETAILS/ALLOC/VALUE

可能是定义了多个删除,所以我必须删除一个或多个元素。

如果:/ROOT/DETAILS/ALLOC/TYPE=UNNEEDED 然后删除:/ROOT/DETAILS/ALLOC/VALUE; /ROOT/DETAILS/ALLOC/otherElement;

+搜索字符串“UNNEEDED”是示例性的,可以是任何东西(名称、描述、标识符)

要通过简单的 xpath 表达式删除节点,删除所有节点上的节点值。按索引删除节点是不可能的。我必须转换一个动态的 xml 结构。结构可以包含此值,但不是必须的。

所以想要的输出是

<ROOT>
    <DETAILS>
        <ALLOC>
            <TYPE>NEEDED</TYPE>
            <VALUE>do not remove</VALUE>
            <NAME>also requiered</NAME>
        </ALLOC>
    </DETAILS>
    <DETAILS>
        <ALLOC>
            <TYPE>UNNEEDED</TYPE>
            - - - - - - - - - - -
            <NAME> but this requiered</NAME>
        </ALLOC>
    </DETAILS>
    <DETAILS>
        <ALLOC>
            <TYPE>NEEDED</TYPE>
            <VALUE>do not remove</VALUE>
            <NAME>also requiered</NAME>
        </ALLOC>
    </DETAILS>
    <SOMEWHERE>
        <OTHERWHERE>
            <TYPE>UNNEEDED</TYPE>
            <VALUE>but do not remove</VALUE>
            <NAME>also requiered</NAME>
        </OTHERWHERE>
    </SOMEWHERE>
</ROOT>

[只有 XPATH: /ROOT/DETAILS/ALLOC 中的元素 'Value' 必须删除,而不是 XPATH /ROOT/SOMEWHERE/OTHERWHERE 中的元素 'Value']

通过无索引的 xpath 表达式删除节点,删除节点 VALUE 此 xpath 上的所有子节点 通过索引 xpath 表达式删除节点也是不可能的,因为我以前不知道索引。给定的 xpath 表达式是无索引的,我必须检查类型的文本值是否为“某物”,然后删除节点“值”。

我只能通过 xml 和 xslt 来解决这个问题。

我想提前谢谢你。

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    试试这个方法:

    XSLT 1.0

    <xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:strip-space elements="*"/>
    
    <!-- identity transform -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="VALUE[../TYPE='UNNEEDED']"/>
    
    </xsl:stylesheet>
    

    补充:

    要将删除仅限于作为ALLOC 子级的VALUE 节点,请使用:

    <xsl:template match="ALLOC[TYPE='UNNEEDED']/VALUE"/>
    

    【讨论】:

    • 感谢 michael.hor257k 的这个想法。我也试过这种方式。它会起作用,但问题是元素的相对路径。可能是相对路径可以在其他地方找到并且也会修改此节点。
    • @Hans.Olo,你的评论有点不清楚。可能是一个样本会有所帮助。
    • @Hans.Olo 如果 VALUE 有一个 sibling TYPE 且值为 "UNNEEDED",这将删除它。如果“在同一级别”是指其他意思,则需要澄清。
    • 大家早上好,我已经编辑了这个问题,并试图更好地解释它。我希望现在更容易理解。
    • 我可以按照你的方法解决这个问题,比较简单。我想已经太复杂了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-02
    • 2012-06-19
    • 1970-01-01
    相关资源
    最近更新 更多