应用不同模式的模板

Apply-templates with different modes

我想使用应用模板处理节点,但使用不同的模式来为序列中的所有节点匹配正确的模板规则。

XML:

<?xml version="1.0" encoding="UTF-8"?>
<story>
    <p class="h1">
        <content>heading</content>
        <br/>
    </p>
    <p>
        <content>some text</content>
        <br/>
        <content>more text...</content>
    </p>
</story>

XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <xsl:element name="div">
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="p">
        <xsl:choose>
            <xsl:when test="@class='h1'">
                <xsl:element name="h1">
                    <!--apply-tempaltes mode:#default, for br mode:ignore-->
                    <xsl:apply-templates/>
                </xsl:element>
            </xsl:when>
            <xsl:otherwise>
                <xsl:element name="p">
                    <!--apply-tempaltes mode:#default-->
                    <xsl:apply-templates/>
                </xsl:element>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <xsl:template match="content" mode="#default">
        <xsl:element name="span">
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="br" mode="#default">
        <xsl:element name="br"/>
    </xsl:template>

    <xsl:template match="br" mode="ignore"/>

</xsl:stylesheet>

想要的输出:

<?xml version="1.0" encoding="UTF-8"?>
<story>
    <h1 class="h1"><span>heading</span>    
    </h1>
    <p><span>some text</span> 
        <br/>
        <span>more text...</span> 
    </p>
</story>

XSLT 版本为 2.0。我知道,还有其他方法可以实现此示例所需的输出,但我想使用模式属性。

AFAICT,你想做的事情:

XSLT 2.0

<xsl:stylesheet version="2.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()" mode="#all">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()" mode="#current"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="p[@class='h1']">
    <h1 class="h1">
        <xsl:apply-templates mode="h1"/>
    </h1>
</xsl:template>

<xsl:template match="content" mode="#all">
    <span>
        <xsl:apply-templates mode="#current"/>
    </span>
</xsl:template>

<xsl:template match="br" mode="h1"/>

</xsl:stylesheet>