xslt中类似字段的模板

template to similar fields in xslt

我的xml文件

...
<element1>
    <year>1</year>
    <month>5</month>
    <days>3</days>
</element1>

<element2>
    <year>2</year>
    <month>4</month>
    <days>5</days>
</element2>
...

我的 xsl-fo 模板

<fo:block>
    <xsl:value-of select="//element1/years"/>
    <xsl:text> years </xsl:text>
    <xsl:value-of select="//element1/month"/>
    <xsl:text> month </xsl:text>
    <xsl:value-of select="//element1/days"/>
    <xsl:text> days </xsl:text>
</fo:block>

...

<fo:block>
    <xsl:value-of select="//element2/years"/>
    <xsl:text> years </xsl:text>
    <xsl:value-of select="//element2/month"/>
    <xsl:text> month </xsl:text>
    <xsl:value-of select="//element2/days"/>
    <xsl:text> days </xsl:text>
</fo:block>

如您所见,这是一个类似的代码块。 我怎样才能简化这个表达式? 应该使用什么样的模板?

我写了一个这样的模板

<xsl:template match="element1">
    <xsl:value-of select="years"/>
    <xsl:text> years </xsl:text>
    <xsl:value-of select="month"/>
    <xsl:text> month </xsl:text>
    <xsl:value-of select="days"/>
    <xsl:text> days </xsl:text>
</xsl:template>       

并使用它

<fo:block>
    <xsl:apply-templates select="element1"/>
</fo:block>

但它不适用于 element2...

嗯,鉴于:

<parent>
  <element1>
    <year>1</year>
    <month>5</month>
    <days>3</days>
  </element1>
  <element2>
    <year>2</year>
    <month>4</month>
    <days>5</days>
  </element2>
</parent>

你可以这样做:

<xsl:template match="parent">
    <fo:wrapper>
        <xsl:for-each select="*">
            <fo:block>
                <xsl:value-of select="year"/>
                <xsl:text> years </xsl:text>
                <xsl:value-of select="month"/>
                <xsl:text> months </xsl:text>
                <xsl:value-of select="days"/>
                <xsl:text> days </xsl:text>
            </fo:block>
        </xsl:for-each>
    </fo:wrapper>
</xsl:template>

获得:

<fo:wrapper>
  <fo:block>1 years 5 months 3 days </fo:block>
  <fo:block>2 years 4 months 5 days </fo:block>
</fo:wrapper>

i don't need to select all elements, i just want to apply this kind of template to elements with similar childs, in deferent places

在这种情况下,您可以调用 命名模板 - 例如:

<xsl:template match="element1">
    <xsl:call-template name="duration"/>
</xsl:template>
...
<xsl:template match="element1">
    <xsl:call-template name="duration"/>
</xsl:template>
...    
<xsl:template name="duration">
    <fo:block>
        <xsl:value-of select="year"/>
        <xsl:text> years </xsl:text>
        <xsl:value-of select="month"/>
        <xsl:text> months </xsl:text>
        <xsl:value-of select="days"/>
        <xsl:text> days </xsl:text>
    </fo:block>
</xsl:template>

鉴于 XML(致谢@michael.hor257k):

<parent>
    <element1>
        <year>1</year>
        <month>5</month>
        <days>3</days>
        <hour>12</hour>
        <minute>32</minute>
    </element1>
    <element2>
        <year>2</year>
        <month>4</month>
        <days>5</days>
        <hour>0</hour>
    </element2>
</parent>

我。匹配模板模式中的多个元素

<xsl:template match="element1 | element2">
  <fo:block>
    <xsl:value-of select="year"/>
    <xsl:text> years </xsl:text>
    <xsl:value-of select="month"/>
    <xsl:text> month </xsl:text>
    <xsl:value-of select="days"/>
    <xsl:text> days </xsl:text>
  </fo:block>
</xsl:template>

二.调用模板

<xsl:template match="element1">
  <xsl:call-template name="renderOutput"/>
</xsl:template>

<xsl:template name="renderOutput">
  <fo:block>
    <xsl:value-of select="year"/>
    <xsl:text> years </xsl:text>
    <xsl:value-of select="month"/>
    <xsl:text> month </xsl:text>
    <xsl:value-of select="days"/>
    <xsl:text> days </xsl:text>
  </fo:block>
</xsl:template>

[默认情况下调用模板中的上下文节点选择调用者的上下文节点!不需要但也可以,继续 <xsl:with-param name="this" select="."/><xsl:value-of select="$this/year"/>]