我有以下示例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
进行一些数学运算。
请让我知道我哪里出错了以及如何解决这个问题。
感谢。
答案 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>
答案 2 :(得分:1)
根据规范:
xsl:template元素的匹配,模式和优先级属性 不影响模板是否由xsl:call-template调用 元件。