请建议。如果数字具有相同的标签,则其ID将重新排序。例如,图3具有相同的标签值,然后下一个图(具有与图3相同的标签)将重新生成为 fig3a,fig3b等。然后XREF的HREF ID也相应地改变(图3,图3a,图3b,图3c等)。请帮助。
XML:
<article>
<floats>
<Figure id="f1"><label>Figure 1</label>The Caption text for Figure.</Figure>
<Figure id="f2"><label>Figure 2</label>The Caption text for Figure.</Figure>
<Figure id="f3"><label>Figure 3</label>The Caption text for Figure.</Figure>
<Figure id="f4"><label>Figure 3</label>The Caption text for Figure.</Figure>
<Figure id="f5"><label>Figure 3</label>The Caption text for Figure.</Figure>
<Figure id="f6"><label>Figure 4</label>The Caption text for Figure.</Figure>
<Figure id="f7"><label>Figure 4</label>The Caption text for Figure.</Figure>
<Figure id="f8"><label>Figure 3</label>The Caption text for Figure.</Figure>
<Figure id="f9"><label>Figure 5</label>The Caption text for Figure.</Figure>
</floats>
<body>
<p>The <xref href="f1">Fig. 1</xref>, <xref href="f5">Fig. 3</xref>b, and <xref href="f9">Fig. 5</xref> are giving detailed info about <xref href="f3 f6 f9">Figs 3-5</xref>.</p>
</body>
</article>
XSLT2.0:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()"><xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy></xsl:template>
<!--xsl:key name="kDupLabel" match="Figure" use="label"/-->
<xsl:template match="Figure">
<xsl:variable name="var1"><xsl:value-of select="label"/></xsl:variable>
<xsl:variable name="var2"><xsl:value-of select="distinct-values(preceding::Figure/label)"/></xsl:variable>
<xsl:variable name="varPresentLabel"><xsl:value-of select="concat('|', ., '|')"/></xsl:variable>
<xsl:variable name="varPrevLabels">
<xsl:for-each select="tokenize($var2, ' ')">
<xsl:value-of select="concat('|', ., '|')"/>
</xsl:for-each>
</xsl:variable>
<xsl:text> </xsl:text>
<xsl:element name="Figure">
<xsl:attribute name="id">
<xsl:choose>
<xsl:when test="contains($varPrevLabels, $varPrevLabels)">
<xsl:value-of select="concat('fig', substring-after(label, ' '))"/>
<xsl:call-template name="tempSubID">
<xsl:with-param name="varN" select="$var1"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise><xsl:value-of select="@id"/></xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template name="tempSubID">
<xsl:param name="varN"/>
<xsl:variable name="varCnt"><xsl:value-of select="count(preceding::Figure[label=$varN])"/></xsl:variable>
<xsl:choose>
<xsl:when test="number($varCnt)=1">a</xsl:when>
<xsl:when test="number($varCnt)=2">b</xsl:when>
<xsl:when test="number($varCnt)=3">c</xsl:when>
<xsl:when test="number($varCnt)=4">d</xsl:when>
<xsl:when test="number($varCnt)=5">e</xsl:when>
<xsl:when test="number($varCnt)=6">f</xsl:when>
<xsl:when test="number($varCnt)=7">g</xsl:when>
<xsl:when test="number($varCnt)=8">h</xsl:when>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
必填结果:
<article><floats>
<Figure id="fig1"><label>Figure 1</label>The Caption text for Figure.</Figure>
<Figure id="fig2"><label>Figure 2</label>The Caption text for Figure.</Figure>
<Figure id="fig3"><label>Figure 3</label>The Caption text for Figure.</Figure>
<Figure id="fig3a"><label>Figure 3</label>The Caption text for Figure.</Figure><!--same label as previous, ID to be 'fig3a'-->
<Figure id="fig3b"><label>Figure 3</label>The Caption text for Figure.</Figure><!--same label as previous, ID to be 'fig3b'-->
<Figure id="fig4"><label>Figure 4</label>The Caption text for Figure.</Figure>
<Figure id="fig4a"><label>Figure 4</label>The Caption text for Figure.</Figure><!--same label as previous, ID to be 'fig4a'-->
<Figure id="fig3c"><label>Figure 3</label>The Caption text for Figure.</Figure><!--same label as previous, ID to be 'fig3c'-->
<Figure id="fig5"><label>Figure 5</label>The Caption text for Figure.</Figure></floats>
<body>
<p>The <xref href="fig1">Fig. 1</xref>, <xref href="fig3b">Fig. 3</xref>b, and <xref href="fig5">Fig. 5</xref> are giving detailed info about <xref href="fig3 fig4 fig5">Figs 3-5</xref>.</p></body></article>
答案 0 :(得分:1)
我认为您可以使用两个键,然后您需要在key
函数返回的序列中找到元素的位置:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="xs mf"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:function name="mf:number-figure">
<xsl:param name="figure" as="element(Figure)"/>
<xsl:variable name="figure-group" select="key('figure-label', $figure/label, root($figure))"/>
<xsl:variable name="prefix" as="xs:string" select="'fig' || replace($figure/label, '[^0-9]+', '')"/>
<xsl:variable name="number" as="xs:string">
<xsl:number
value="index-of($figure-group/generate-id(), generate-id($figure)) - 1"
format="a"/>
</xsl:variable>
<xsl:sequence
select="if ($figure is $figure-group[1])
then $prefix
else $prefix || $number"/>
</xsl:function>
<xsl:key name="figure-ref" match="Figure" use="@id"/>
<xsl:key name="figure-label" match="Figure" use="label"/>
<xsl:template match="Figure/@id">
<xsl:attribute name="{name()}" select="mf:number-figure(..)"/>
</xsl:template>
<xsl:template match="xref/@href">
<xsl:attribute name="{name()}"
select="tokenize(., '\s+')!mf:number-figure(key('figure-ref', ., root(current())))"/>
</xsl:template>
</xsl:stylesheet>
这是http://xsltfiddle.liberty-development.net/bFukv8k/1在线的XSLT 3,但当然关键用途也可以在XSLT 2中完成,你所需要的就是拼出xsl:mode
作为身份转换,转换任何使用||
至concat
次调用以及!
对for $v in exp return ...
的任何使用,如http://xsltransform.hikmatu.com/b4GWV9中所述。