在元素上多次应用模板

时间:2014-08-13 09:09:22

标签: xslt

我在以下方面苦苦挣扎。鉴于项目可能包含多个零件和规格对,我想处理每一对,或多次将模板应用于项目。 目前,每个项目都处理一次,我错过了第二部分。

<figure>
    <list>
        <item>
            <part>
                <p>74174</p>
            </part>
            <spec>
                <u>a1</u>
            </spec>
            <part>
                <p>75375</p>
            </part>
            <spec>
                <u>a4</u>
            </spec>
        </item>
    </list>
</figure>

样式表:

<xsl:if test="$a = 'abc'">
    <xsl:apply-templates mode="pt" select="/figure/list/item" />
</xsl:if>

<xsl:template mode="pt" match="item[./part]">
    <xsl:call-template name="ptt">
        <xsl:with-param name="p"><xsl:value-of select="part/p"/>
        </xsl:with-param>
        <xsl:with-param name="pr">
            <xsl:if test="spec/u">
                <xsl:element name="pr">
                    <xsl:element name="rpn">
                        <xsl:value-of select="spec/u"/>
                    </xsl:element>
                    <xsl:element name="rtn">Alt</xsl:element>
                </xsl:element>
            </xsl:if>
        </xsl:with-param>
    </xsl:call-template>
</xsl:template>

我对代码进行了简化和裁剪,因为它一直在继续......

编辑:下一个是仅根据输入参数生成我的新元素

<xsl:template name="ptt">
    <xsl:param name="p"/>
    <xsl:param name=u"/>
</xsl:template>

2 个答案:

答案 0 :(得分:0)

使用call-template和参数<xsl:with-param name="p"><xsl:value-of select="part/p"/></xsl:with-param>使得它变得比它需要的更难,假设XSLT 1.0 <xsl:with-param name="p"><xsl:value-of select="part/p"/></xsl:with-param>用文本节点填充参数ppart/p选择的第一个元素的字符串值。因此,至少只使用<xsl:with-param name="p-elements" select="part/p"/>,然后参数值是包含所有p元素的节点集。

更好的是,只需一致地使用模板匹配和应用模板,然后您就不必为call-templatewith-param而烦恼。

根据您的评论,您可以使用

<xsl:template mode="pt" match="item[part]">
  <xsl:apply-templates select="part" mode="pt"/>
</xsl:template>

<xsl:template match="part" mode="pt">
  <xsl:variable name="spec" select="following-sibling::*[1][self::spec]"/>
  ...
</xsl:template>

答案 1 :(得分:0)

您似乎不愿意展示一个独立而完整的示例(对于您未来的问题,不要让人们很难帮助您),所以我不确定以下内容对您是否有帮助

假设您显示的XML输入,下面的样式表演示了一种方法,可以根据您的要求为每对specpart元素调用命名模板。

它使用xsl:for-each-group(XSLT 2.0独有,但您没有告诉使用哪个版本的XSLT)来定义以part元素开头的组,从而产生所述对。然后,对于每个组,使用pttp作为参数调用命名模板u

<强>样式表

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

    <xsl:strip-space elements="*"/>
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/>

    <xsl:template match="item">
        <xsl:for-each-group select="*" group-starting-with="part">
            <xsl:call-template name="ptt">
                <xsl:with-param name="p" select="current-group()[1]/p"/>
                <xsl:with-param name="u" select="current-group()[2]/u"/>
            </xsl:call-template>
        </xsl:for-each-group>
    </xsl:template>

    <xsl:template name="ptt">
        <xsl:param name="p"/>
        <xsl:param name="u"/>

        <result>
            <part><xsl:value-of select="$p"/></part>
            <spec><xsl:value-of select="$u"/></spec>
        </result>
    </xsl:template>

</xsl:transform>

XML输出

<?xml version="1.0" encoding="UTF-8"?>
<result>
   <part>74174</part>
   <spec>a1</spec>
</result>
<result>
   <part>75375</part>
   <spec>a4</spec>
</result>