XSLT:多次处理相同的元素

时间:2016-08-17 20:23:36

标签: xml xslt-1.0

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

我提供了ab等模板。

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

1 个答案:

答案 0 :(得分:0)

在典型情况下(有许多例外情况),您将递归地处理节点,遍历树从根到叶。然后你的样式表将按照以下方式构建:

<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元素并使其成为根元素的兄弟元素,您可以执行以下操作: p>

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文档。