跳过一个元素及其所有子元素

Skip an element and all its child elements

有没有办法跳过特定元素及其所有子元素 elements.for 例如:

1. Audi
    1.1 Engine
            1.1.1 Piston
            1.1.2 Crankshaft
    1.2 Transmission
            1.2.1 Gears
            1.2.2 Shift

2. Ferrari
    2.1 Engine
            2.1.1 Piston
            2.1.2 Crankshaft
    2.2 Transmission
            2.2.1 Gears
            2.2.2 Shift
    

3. Ford
    3.1 Engine
            3.1.1 Piston
            3.1.2 Crankshaft
    3.2 Transmission
            3.2.1 Gears

这是 XML 文档

 <?xml version="1.0" encoding="UTF-8"?>
<Hierarchy>
    <Board>
        <Name>Audi</Name>
        <Id>ABCDE</Id>
        <ParentId></ParentId>
        <General>
            <Name>Audi</Name>
            <Description>Car brand</Description>
            <Template>LEVEL1</Template>
        </General>
    </Board>
    <Board>
        <Name>Engine</Name>
        <Id>EFGHI</Id>
        <ParentId>ABCDE</ParentId>
        <General>
            <Name>Engine</Name>
            <Description>Part of Car</Description>
            <Template>LEVEL2</Template>
        </General>
    </Board>
    <Board>
        <Name>Piston</Name>
        <Id>JKLMN</Id>
        <ParentId>EFGHI</ParentId>
        <General>
            <Name>Department_Heads</Name>
            <Description>Part of Engine</Description>
            <Template>LEVEL3</Template>
        </General>
    </Board>
    <Board>
        <Name>Crankshaft</Name>
        <Id>OPQRS</Id>
        <ParentId>EFGHI</ParentId>
        <General>
            <Name>Department_Heads</Name>
            <Description>Part of Engine</Description>
            <Template>LEVEL3</Template>
        </General>
    </Board>
    <Board>
        <Name>Transmission</Name>
        <Id>TUVWX</Id>
        <ParentId>ABCDE</ParentId>
        <General>
            <Name>Transmission</Name>
            <Description>Part of Car</Description>
            <Template>LEVEL2</Template>
        </General>
    </Board>
    <Board>
        <Name>Gear</Name>
        <Id>CSDKL</Id>
        <ParentId>TUVWX</ParentId>
        <General>
            <Name>Gear</Name>
            <Description>Part of Transmission</Description>
            <Template>LEVEL3</Template>
        </General>
    </Board>
    <Board>
        <Name>Shift</Name>
        <Id>SDKLFH</Id>
        <ParentId>TUVWX</ParentId>
        <General>
            <Name>Shift</Name>
            <Description>Part of Transmission</Description>
            <Template>LEVEL3</Template>
        </General>
    </Board>
</Hierarchy>

假设我只想跳过 audi 及其所有子元素中的“引擎”,我该怎么做?

我通常创建 xslt 并提及 XML 文件中的一些属性,例如 Id 等。但这是一个漫长的过程,因为我还必须键入 Engine 的所有子元素的 Id。当我有 100k 个元素时变得更加复杂。

预期输出为:

<?xml version="1.0" encoding="UTF-8"?>
<Hierarchy>
    <Board>
        <Name>Audi</Name>
        <Id>ABCDE</Id>
        <ParentId></ParentId>
        <General>
            <Name>Audi</Name>
            <Description>Car brand</Description>
            <Template>LEVEL1</Template>
        </General>
    </Board>
    
    <Board>
        <Name>Transmission</Name>
        <Id>TUVWX</Id>
        <ParentId>ABCDE</ParentId>
        <General>
            <Name>Transmission</Name>
            <Description>Part of Car</Description>
            <Template>LEVEL2</Template>
        </General>
    </Board>
    <Board>
        <Name>Gear</Name>
        <Id>CSDKL</Id>
        <ParentId>TUVWX</ParentId>
        <General>
            <Name>Gear</Name>
            <Description>Part of Transmission</Description>
            <Template>LEVEL3</Template>
        </General>
    </Board>
    <Board>
        <Name>Shift</Name>
        <Id>SDKLFH</Id>
        <ParentId>TUVWX</ParentId>
        <General>
            <Name>Shift</Name>
            <Description>Part of Transmission</Description>
            <Template>LEVEL3</Template>
        </General>
    </Board>
</Hierarchy>

请注意,我只提到了层次结构的“奥迪”部分,对于法拉利和福特,我需要输出中的所有数据。

中所述,这很复杂,因为元素与其祖先之间没有直接联系。需要一个临时步骤来找到您要删除的部分的所有后代 - 例如:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:param name="remove-id">EFGHI</xsl:param>

<xsl:key name="children" match="Board" use="ParentId" />

<xsl:template match="/Hierarchy">
    <!-- construct a list of Ids to remove -->
    <xsl:variable name="blacklist">
        <Id>
            <xsl:value-of select="$remove-id"/>
        </Id>
        <xsl:apply-templates select="key('children', $remove-id)" mode="blacklist"/>
    </xsl:variable>
    <!-- output -->
    <xsl:copy>
        <xsl:copy-of select="Board[not(Id = exsl:node-set($blacklist)/Id)]"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="Board" mode="blacklist">
    <xsl:copy-of select="Id"/>
    <xsl:apply-templates select="key('children', Id)" mode="blacklist"/>
</xsl:template>

</xsl:stylesheet>