你应该用不同的
modes
对于模板(这需要添加
mode
属性到所有
xsl:template
和
xsl:apply-templates
陈述)。然后,默认模式下根节点的模板将首先在第一种模式下触发根模板,然后在第二种模式下将结果传递给根模板。为此,您需要能够将结果树片段(这是元素构造函数生成的)视为节点集(这是您可以将模板应用到的节点集,或者通过xpath进行查询的节点集)-没有标准的方法可以做到这一点,但是
exsl:node-set
是一个事实上的标准(请注意,支持它的处理器的完整列表大于该页上的内容-例如,.net
XslCompiledTransform
支持它)。所以:
<xsl:template match="/">
<xsl:variable name="round1-output">
<xsl:apply-templates select="/" mode="round1" />
</xsl:variable>
<xsl:apply-templates select="exsl:node-set($round1-output)" mode="round2" />
</xsl:template>
<xsl:template match="/" mode="round1">
...
<xsl:apply-templates mode="round1" />
...
</xsl:template>
<xsl:template match="/" mode="round2">
...
<xsl:apply-templates mode="round2" />
...
</xsl:template>
...
<xsl:template match="xs:complexType" mode="round1">
<xsl:param name="prefix" />
<xs:complexType name="{my:updateName($prefix, @name)}">
<!-- insert xs:sequence ONLY if the child is NOT xs:complexContent -->
<xsl:choose>
<xsl:when test="*[name()='xs:complexContent']">
<xsl:apply-templates select="node()" mode="round1"/>
</xsl:when>
<xsl:otherwise>
<xs:sequence>
<xsl:apply-templates select="node()" mode="round1"/>
</xs:sequence>
</xsl:otherwise>
</xsl:choose>
</xs:complexType>
<xsl:apply-templates select=".//xs:element" mode="round1"/>
</xsl:template>
<xsl:template match="xs:complexType" mode="round2">
<xsl:copy>
<xsl:apply-templates select="*|@*" mode="round2"/>
</xsl:copy>
</xsl:template>