XSLT:多次处理同一个元素



我想知道下面的XSLT(1.0)是否可以。我有一个XML模式,它定义了一个元素a,其中可能包含元素bc等。然而,a可能递归地出现在a中。

我为a, b等提供模板

<xsl:template match="/">
    <xsl:for-each select="a">
        <!-- matches also a nested <a>-->
        <xsl:apply-templates/>      
        <!-- matches only nested <a> (this has already been matched before) -->
        <xsl:for-each select="a">
            <xsl:apply-templates/>                
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>
<!-- for nested <a> -->
<xsl:template match="a">
    <!-- do some stuff here -->
</xsl:template>
<xsl:template match="b">
    <!-- do some stuff here -->
</xsl:template>
<xsl:template match="c">
    <!-- do some stuff here -->
</xsl:template>

给定以下XML, a中的每个a被处理两次:

<a>
    <b> .... </b>
    <a><b> ... </b></a>
</a>
像这样,我可以在a之后添加一个嵌套的a:
<a>
    <b> .... </b>

</a>
<a><b> ... </b></a> 

我想知道这是有效的XSLT 1.0和预期的行为,还是应该被其他东西取代的hack。

在典型情况下(有许多例外),您将递归地处理节点,从根到叶遍历树。那么你的样式表的结构应该是:

<xsl:template match="a">
    <!-- do some stuff here -->
    <xsl:apply-templates/>
</xsl:template>
<xsl:template match="b">
    <!-- do some stuff here -->
     <xsl:apply-templates/>
</xsl:template>
<xsl:template match="c">
    <!-- do some stuff here -->
</xsl:template>

为了以不同的方式处理根a,您可以这样做:

<xsl:template match="/a">
    <!-- do some stuff here -->
    <xsl:apply-templates/>
</xsl:template>
<xsl:template match="a">
    <!-- do some other stuff here -->
    <xsl:apply-templates/>
</xsl:template>
<xsl:template match="b">
    <!-- do some stuff here -->
     <xsl:apply-templates/>
</xsl:template>
<xsl:template match="c">
    <!-- do some stuff here -->
</xsl:template>

参见:https://www.w3.org/TR/xslt/#section-Processing-Model


补充道:

要执行在您编辑的问题中显示的转换-即移动a元素是根a元素的子元素,并使它们成为根元素的兄弟元素,您可以这样做:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>
<xsl:template match="/a">
    <xsl:copy>
        <xsl:apply-templates select="b"/>
    </xsl:copy>
    <xsl:apply-templates select="a"/>
</xsl:template>
</xsl:stylesheet>

然而,结果是:

<a>
   <b> .... </b>
</a>
<a>
   <b> ... </b>
</a>

有两个根元素,因此不是一个格式良好的XML文档。

相关内容

  • 没有找到相关文章

最新更新