我有一个xml文档,看起来像这样:
<chapter>
<para>Just a random text<cross-ref refid="1234">Abb. 1.0</cross-ref>Some more text</para>
<section-title>Title</section-title>
<para>and more text text ext<cross-ref refif="1234">Abb 1.0</cross-ref>more more more</para>
</chapter>
正如您所看到的,段落中有两个cross-ref
元素。它们基本上可以在任何地方出现,并且可以通过refid
(但不是唯一的)来识别。我目前要做的是在第一次出现的位置插入一个图像(基于refid
),同时将文本保持为标题。每个其他出现(不是第一个)应该只是包含插入图像的内部基本链接的内联文本。
我目前的解决方案是:
<xsl:template match="cross-ref">
<xsl:choose>
<xsl:when test="position() = 1">
<fo:block text-align="center" id="{@refid}">
<xsl:variable name="refVar" select="@refid"/>
<xsl:variable name="imageName" select="/chapter/floats/figure[@id=$refVar]/link/@locator" />
<fo:external-graphic src="url({concat($imageName, '.jpg')})" />
<fo:block text-align="center" xsl:use-attribute-sets="lit-para">
<xsl:value-of select="current()" />
</fo:block>
</fo:block>
</xsl:when>
<xsl:otherwise>
<fo:basic-link internal-destination="{@refid}">
<xsl:value-of select="current()" />
</fo:basic-link>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
它确实适用于某些情况,但由于position()
并非始终为1,因此某些图像未正确插入。我有什么选择?
谢谢!
refid
。从而。每个refid
只有一个图片,而每个其他cross-ref
元素都有refid
个指向该图片
答案 0 :(得分:1)
您必须更改xsl:when
中的测试,以便仅对每个@ref-id
值的第一次出现都是如此;换句话说,您必须检查前面的cross-ref
元素是否具有相同的@ref-id
:
<xsl:when test="not(preceding::cross-ref[@ref-id = current()/@ref_id])">
...
答案 1 :(得分:1)
如果您使用的是XSLT 2.0或XSLT 3.0,则添加xsl:key
作为顶级元素:
<xsl:key name="cross-ref" match="cross-ref" use="@refid" />
然后您可以将xsl:when
更改为:
<xsl:when test=". is key('cross-ref', @refid)[1]">
这是有效的,因为key()
按文档顺序(https://www.w3.org/TR/xslt20/#keys)返回节点。这可能比使用preceding
轴更快(在大型文档上),但是要确保您必须通过使用XSLT处理器运行文档来测试它。
如果你正在使用XSLT 1.0,那么你必须使用类似Meunchian Grouping的技巧来做这件事:
<xsl:when test="count(. | key('cross-ref', @refid)[1]) = 1">
但是这比XSLT 2.0版本的可读性低得多。