尽管声明了,但无法匹配模式

时间:2015-01-19 08:18:53

标签: xslt xslt-2.0

我有以下示例XML。

<toc>
<toc-part>
<toc-div>

<toc-item num="IV."><toc-title>New</toc-title><toc-pg>1.065</toc-pg><page number="1"/></toc-item>
</toc-div>
</toc-part>
</toc>
<section>
    <para>
        This is content<page number="3"/>
    </para>
</section>

来自section,我正在尝试使用以下XSL获取第一个页码值。

 <xsl:template match="section">
        <xsl:call-template name="pageCount"/>
    </xsl:template>
<xsl:template name="pageCount" match="//page[1]">
<div class="number">
<xsl:value-of select="./@number"/>
</div>
</xsl:template>

但显示为空。

当前输出<div class="number"></div> 预期输出<div class="number">1</div>

我在这里使用这种方法,因为我需要对第一个和第二个page number进行一些数学运算。

请让我知道我哪里出错了以及如何解决这个问题。

Demo

感谢。

3 个答案:

答案 0 :(得分:3)

call-template不会更改上下文节点,因此您使用section的上下文节点调用pageCount模板,该节点没有number属性。

您需要应用于相关元素,而不是按名称调用模板:

<xsl:apply-templates select="descendant::page[1]"/>

并使匹配模式更加通用,例如page代替//page[1]。使用apply-templates 会根据需要更改上下文。

如果您需要在其他情况下以不同方式处理相同的元素,您可能需要考虑在模板上使用模式

<xsl:template match="section">
  <xsl:apply-templates mode="pageCount"
        select="descendant::page[1]"/>
</xsl:template>

<xsl:template mode="pageCount" match="page">
  <div class="number">
    <xsl:value-of select="./@number"/>
  </div>
</xsl:template>

编辑:如果你确实希望每个 section从同一个page元素中取出数字(整个文档中的第一个而不是该部分中的第一个),那么您可以将模板应用于(//page)[1]而不是descendant::page[1]

请注意这里的括号 - (//page)[1]//page[1]不同。前者最多选择一个节点(文档中的第一个page),后者可以选择多个(每个page元素,它是其各自父节点中的第一个page,所以在您的示例中,这将是编号为1 3)的页面。

答案 1 :(得分:2)

调用命名模板不会更改上下文。我不确定您为什么需要命名模板,但如果必须,请将其更改为:

<xsl:template name="pageCount">
    <div class="number">
        <xsl:value-of select="(//page/@number)[1]"/>
    </div>
</xsl:template>

更新了演示:http://xsltransform.net/nc4NzQj/1

答案 2 :(得分:1)

根据规范:

  

xsl:template元素的匹配,模式和优先级属性   不影响模板是否由xsl:call-template调用   元件。