尽管已声明但无法匹配模式

unable to match a pattern though declared

我有下面的示例 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

谢谢。

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>

编辑:如果你真的想要 every section 从相同的 page 元素中提取数字([=39 中的第一个=]whole document 而不是 that section) 中的第一个)然后你可以将模板应用到 (//page)[1] 而不是 descendant::page[1].

请注意此处的括号 - (//page)[1]//page[1] 不同。前者最多select个节点(文档中的第一个page),后者可能select多个(每个page元素是第一个page 在其各自的父级中,因此在您的示例中,这两个页面都编号为 1 3).

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

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

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

根据规范:

The match, mode and priority attributes on an xsl:template element do not affect whether the template is invoked by an xsl:call-template element.