<comp>
<section id="1">
<p>text</p>
<figure xml:id="c1-fig-002"/>
<p>text</p>
<figure xml:id="c1-fig-003"/>
</section>
<section id="2">
<p>text</p>
<figure xml:id="c1-fig-003"/>
<figure xml:id="c1-fig-004" resumeNumberingAt="7"/>
<figure xml:id="c1-fig-005"/>
<p>text</p>
</section>
<section id="3">
<p>text</p>
<figure xml:id="c1-fig-006"/>
<figure xml:id="c1-fig-007" resumeNumberingAt="18"/>
<p>text</p>
<figure xml:id="c1-fig-008"/>
<p>text</p>
<figure xml:id="c1-fig-009"/>
</section>
</comp>
我正在使用xslt获得以下结果,
<comp>
<section id="1">
<p>text</p>
<figure xml:id="c1-fig-002"/>
<fignum>2</fignum>
<p>text</p>
<figure xml:id="c1-fig-003"/>
<fignum>3</fignum>
</section>
<section id="2">
<p>text</p>
<figure xml:id="c1-fig-003"/>
<fignum>3</fignum>
<figure xml:id="c1-fig-004" resumeNumberingAt="7"/>
<fignum>7</fignum>
<figure xml:id="c1-fig-005"/>
<fignum>8</fignum>
<p>text</p>
</section>
<section id="3">
<p>text</p>
<figure xml:id="c1-fig-006"/>
<fignum>9</fignum>
<figure xml:id="c1-fig-007" resumeNumberingAt="18"/>
<fignum>18</fignum>
<p>text</p>
<figure xml:id="c1-fig-008"/>
<fignum>19</fignum>
<p>text</p>
<figure xml:id="c1-fig-009"/>
<fignum>20</fignum>
</section>
</comp>
我需要从2
的{{1}}之后的数字中获取值。
如果有一个属性resumeNumberingAt,那么我需要使用该值而不是正常值,并增加以下节点的值。我使用以下xslt来做到这一点,但它不起作用。
c1-fig-002
答案 0 :(得分:1)
此XSLT 1.0样式表......
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="figure">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
<fignum>
<xsl:variable name="base-node" select="
((preceding::figure[@resumeNumberingAt] |
self ::figure[@resumeNumberingAt] )[last()] |
self ::figure)[1]" />
<xsl:variable name="base">
<xsl:apply-templates select="$base-node" mode="numbering" />
</xsl:variable>
<xsl:variable name="prev-figs" select="preceding::figure" />
<xsl:variable name="prev-fig-count" select="count($prev-figs)" />
<xsl:value-of select="$base +
count(($base-node/following::figure|$base-node)
[count(. | $prev-figs) = $prev-fig-count])" />
</fignum>
</xsl:template>
<xsl:template match="figure[@resumeNumberingAt]" mode="numbering">
<xsl:value-of select="@resumeNumberingAt" />
</xsl:template>
<xsl:template match="figure" mode="numbering">
<xsl:value-of select="substring(@xml:id, 8, 3)" />
</xsl:template>
</xsl:stylesheet>
...获取您的样本输入文档并生成所述的预期输出文档。此解决方案已在Microsoft XslCompiledTransform XSLT引擎
上成功测试在无模式图模板中,我们将复制输入图元素并创建以下fignum元素。变量$ base-node将是我们基于该图号的基本节点。看一下细节,这个表达......
(preceding::figure[@resumeNumberingAt] |
self ::figure[@resumeNumberingAt] )[last()]
...将引用具有@resumeNumberingAt属性的最近的前一个数字元素,或者如果此属性具有@resumeNumberingAt属性,则引用此对象(焦点节点)。一般来说,这将是我们计算fignum的基础。但是,当焦点节点在第一个@resumeNumberingAt之前时,一个例外。在这种情况下,我们将基于上下文节点的计数(通过xml:id属性)。因此,在所有情况下,我们都可以找到基节点,没有任何带有此表达式的笨拙的xsl:if语句......
((preceding::figure[@resumeNumberingAt] |
self ::figure[@resumeNumberingAt] )[last()] |
self ::figure)[1]
现在计算基数。我们有基节点。如果它具有@resumeNumberingAt属性,那么这是基数,否则它基于@xml:id属性。而不是做一个明确的测试,我们可以简单地利用模板选择机制和模式来计算基数。例如,对于节点...
<figure xml:id="c1-fig-006"/>
......基本节点是......
<figure xml:id="c1-fig-004" resumeNumberingAt="7"/>
...因此基数为7.稍后需要将此偏移+2以获得所需的fignum 9.相反,对于节点......
<figure xml:id="c1-fig-003"/>
...基本节点本身,基值为3('003'转换为整数)。稍后将需要将此偏移+0以获得所需的fignum 3。
变量$ prev-figs是此前一个数字元素的集合。所以现在我们通过将基本fignum偏移基本节点和焦点节点(包括基节点,但不包括焦点节点)之间的数字计算来计算fignum。这个偏移是两组之间的交集:
(1)以下(包括)基节点的数字;和
(2)焦点节点之前的数字。
在XSLT 1.0中,计算两组交集的一般方法是......
$node-set1[count(. | $node-set2) = count($node-set2)]
......而这正是我们对这条指令的所作所为......
<xsl:value-of select="$base +
count(($base-node/following::figure|$base-node)
[count(. | $prev-figs) = $prev-fig-count])" />
采用以下一般原则: