XSLT将模板应用于树部件

时间:2013-04-16 16:49:56

标签: xslt

我有XML树:

<text>
    <plain>abcd<c>efgh</c>ijklm</plain>
    <plain>nopq<c>rst</c>uvw<c>xyz</c></plain>
    <rp><first><c>asdasd</c>asf</first><second>asdasd</second></rp>
    <plain>aaaaa<c>bbbb</c>ccccc<c>xyz</c></plain>
</text>

然后我的XSLT样式表中有代码($ product_text包含上面的树):

<xsl:template name="text_list">
<xsl:if test="$text_count &gt; 0">
    <xsl:apply-templates mode="text_item" select="$product_text/text">
        <xsl:sort select="@rating" order="descending" data-type="number" />
    </xsl:apply-templates>
</xsl:if>
</xsl:template>

<xsl:template mode="text_item" match="*">
    <div class="cmp-post">
        <xsl:copy-of select="./*" />
    </div>
</xsl:template>

此片段按原样复制所有树。但是我需要像这样替换/修改所有“c”节点:

<c>efgh</c>
to
<cmp attr="efgh">efgh</c>

<c>rst</c>
to
<cmp attr="rst">rst</c>
etc

(已编辑)结果我期待:

<div class="cmp-post">
    <plain>abcd<c attr="efgh">efgh</c>ijklm</plain>
    <plain>nopq<c attr="rst">rst</c>uvw<c attr="xyz">xyz</c></plain>
    <rp><first><c attr="asdasd">asdasd</c>asf</first><second>asdasd</second></rp>
    <plain>aaaaa<c attr="bbbb">bbbb</c>ccccc<c attr="xyz">xyz</c></plain>
</div>

我应该如何修改text_item模板?

1 个答案:

答案 0 :(得分:1)

基本上,您希望apply-templates代替copy-ofcopy-of只复制节点;它不会对复制的元素进行模板匹配和调用。

因此,您需要一些额外的模板来获得您想要的内容。

<!-- Copy attributes as-is -->
<xsl:template match="@*" mode="text_item">
    <xsl:copy-of select="."/>
</xsl:template>

<!-- By default, copy element and text as-is then apply matching on children -->
<xsl:template match="node()" mode="text_item">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()" mode="text_item"/>
    </xsl:copy>
</xsl:template>

<!-- For 'text' elements, use div instead of direct copy -->
<xsl:template match="text" mode="text_item">
    <div class="cmp-post">
        <xsl:apply-templates mode="text_item" />
    </div>
</xsl:template>

<xsl:template match="c" mode="text_item">
    <xsl:copy>
        <xsl:attribute name='attr'><xsl:value-of select="."/></xsl:attribute>
        <xsl:apply-templates mode="text_item" />
    </xsl:copy>
</xsl:template>

(请注意,@*模板仅用于完整性。您当前的输入没有任何属性,但如果确实如此,则会将它们复制到输出中。)

使用此作为调用者

在输入上运行上述模板
<xsl:template match="/">
    <xsl:apply-templates select="." mode="text_item">
  <xsl:sort select="@rating" order="descending" data-type="number" />
    </xsl:apply-templates>
</xsl:template>

给出输出

<div class="cmp-post">
    <plain>abcd<c attr="efgh">efgh</c>ijklm</plain>
    <plain>nopq<c attr="rst">rst</c>uvw<c attr="xyz">xyz</c></plain>
    <rp><first><c attr="asdasd">asdasd</c>asf</first><second>asdasd</second></rp>
    <plain>aaaaa<c attr="bbbb">bbbb</c>ccccc<c attr="xyz">xyz</c></plain>
</div>

在针对节点变量调用时应该是相同的。