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

时间:2021-07-27 04:18:07

标签: xslt xslt-1.0

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

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>

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

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

预期输出为:

<?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>

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

1 个答案:

答案 0 :(得分:0)

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

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>