在 XSLT1.0 中实现此目的的一种方法是定义一个键,该键按具有较低级别的最前面的兄弟元素对元素进行分组
<xsl:key
name="companies"
match="Company"
use="generate-id(preceding-sibling::Company[Level < current()/Level][1])" />
然后,假设您定位在您想要较低级别的特定公司元素上,您可以这样做
这将首先获得下一个级别的元素。要获得后续级别,您需要一个模板来匹配公司元素,复制它们并递归应用模板
<xsl:template match="Company">
<Company>
<xsl:apply-templates select="@*|node()"/>
</Company>
<xsl:apply-templates select="key('companies', generate-id())" />
</xsl:template>
这是完整的 XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="companies" match="Company" use="generate-id(preceding-sibling::Company[Level < current()/Level][1])" />
<xsl:template match="/Companies">
<xsl:apply-templates select="Company[Name='A']" mode="parent" />
</xsl:template>
<xsl:template match="Company" mode="parent">
<xsl:apply-templates select="key('companies', generate-id())" />
</xsl:template>
<xsl:template match="Company">
<Company>
<xsl:apply-templates select="@*|node()"/>
</Company>
<xsl:apply-templates select="key('companies', generate-id())" />
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
应用于您的示例 XML 时,将输出以下内容
<Company>
<Name>B</Name>
<Level>1</Level>
</Company>
<Company>
<Name>C</Name>
<Level>1</Level>
</Company>