跳过元素及其所有子元素

  • 本文关键字:元素 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等。但这是一个漫长的过程,因为我必须键入引擎的所有子元素的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>

最新更新