我有一堆包含calstables的内容,其中的脚注是使用排版技术完成的,每个索引都是使用<sup/>元素设置的,每个脚注都包含在表格末尾的自己的跨行中。
我想将它们转换为使用Docbook脚注标记,如this和this
示例数据如下所示(我添加了<from/>和<to/>元素,以显示它来自何处以及需要转到何处)
<testdata>
<from>
<table>
<tgroup cols="3">
<colspec colname="1" colnum="1" colwidth="39pt" align="left"/>
<colspec colname="2" colnum="2" colwidth="39pt" align="center"/>
<colspec colname="3" colnum="3" colwidth="39pt" align="center"/>
<thead>
<row valign="bottom">
<entry>Item</entry>
<entry>ItemA</entry>
<entry>ItemB<sup>1</sup></entry>
</row>
</thead>
<tbody>
<row valign="top">
<entry>Entry 1</entry>
<entry>60</entry>
<entry>3.2</entry>
</row>
<row>
<entry>Entry A</entry>
<entry>150</entry>
<entry>3.55<sup>2</sup></entry>
</row>
<row>
<entry>This entry</entry>
<entry>260<sup>3</sup></entry>
<entry>3.55<sup>2</sup></entry>
</row>
<row>
<entry align="left" namest="1" nameend="3"><sup>1</sup> LAT</entry>
</row>
<row>
<entry align="left" namest="1" nameend="3"><sup>2</sup> Itemvalue <24.5 m. Also see note below.</entry>
</row>
<row>
<entry align="left" namest="1" nameend="3"><sup>3</sup> Ramp up 19.8 m.</entry>
</row>
</tbody>
</tgroup>
</table>
</from>
<to>
<table>
<tgroup cols="3">
<colspec colname="1" colnum="1" colwidth="39pt" align="left"/>
<colspec colname="2" colnum="2" colwidth="39pt" align="center"/>
<colspec colname="3" colnum="3" colwidth="39pt" align="center"/>
<thead>
<row valign="bottom">
<entry>Item</entry>
<entry>ItemA</entry>
<entry>ItemB<footnote id="1">LAT</footnote></entry>
</row>
</thead>
<tbody>
<row valign="top">
<entry>Entry 1</entry>
<entry>60</entry>
<entry>3.2</entry>
</row>
<row>
<entry>Entry A</entry>
<entry>150</entry>
<entry>3.55<footnote id="2">Itemvalue <24.5 m. Also see note below.</footnote></entry>
</row>
<row>
<entry>This entry</entry>
<entry>260<footnote id="3">Ramp up 19.8 m.</footnote></entry>
<entry>3.55<footnoteref linkend="2"/></entry>
</row>
</tbody>
</tgroup>
</table>
</to>
</testdata>逻辑相当简单明了:
1. Copy everthing to output, unless ...
2. it contains a `<sup/>` element, in which case either
1. if it has a `@nameend` attribute, do nothing, or
2. if it is the first instance of this index, create a footnote element with an `@id` attribute, grabbing the content from the matching straddle row, or
3. if it's not the first instance, create a footnoteref element, with a matching `@linkend` attribute当然也有一堆错误检查,但我现在不太担心这一点。
我可以使用一堆单独的匹配模式来解决上面的#2中的每一个,比如
<xsl:template match="sup[text() = '1'][1]">
<xsl:template match="sup[text() = '2'][1]">
<xsl:template match="sup[text() = '3'][1]">但我认为一定有更优雅的匹配模式(也许使用键?)来匹配使用的每个索引的第一个实例,但对于我来说,我无法想象它可能是什么。
到目前为止,我已经定义了2个键
<xsl:key name="fn-indices" match="sup" use="number(.)"/>
<xsl:key name="fn-text" match="entry[sup][@nameend > @namest]" use="number(sup)"/>但我不确定如何最好地使用它们?
对于每个索引的第一个实例,对于优雅的匹配模式有什么建议吗?
发布于 2020-06-16 23:40:06
sup[. is key('fn-indices', number())[1]]应该与每个“组”中的第一项匹配,因此您应该能够替换
<xsl:template match="sup[text() = '1'][1]">
<xsl:template match="sup[text() = '2'][1]">
<xsl:template match="sup[text() = '3'][1]">使用
<xsl:template match="sup[. is key('fn-indices', number())[1]]">is操作符检查节点身份。
发布于 2020-06-17 22:25:31
所以我想出了这个模板,它似乎可以做我想做的事情
注意:我已经将footnote缩短为fn,将footnoteref缩短为fnref,以避免与其他进程发生冲突。
此外,我使用的是兼容1.0的generate-id(),而不是is,但我可能会在适当的时候对其进行更改
<xsl:template match="sup" mode="sup2fn" priority="10">
<xsl:variable name="index" select="number(normalize-space(.))"/>
<xsl:variable name="this-table" select="ancestor::*[local-name() = 'table']"/>
<xsl:variable name="fn-text-nodes" select="key('fn-text',$index)[generate-id(ancestor::*[local-name() = 'table']) = generate-id($this-table)][1]"/>
<xsl:variable name="idref-here" select="generate-id(.)"/>
<xsl:variable name="instance-1" select="key('fn-indices',$index)[generate-id(ancestor::*[local-name() = 'table']) = generate-id($this-table)][1]"/>
<xsl:variable name="idref-target" select="generate-id($instance-1)"/>
<xsl:variable name="fn-text">
<xsl:apply-templates select="$fn-text-nodes/node()" mode="make-footnote-text"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="generate-id(.) = generate-id($instance-1) ">
<fn id="{$idref-here}">
<xsl:if test="$debug = 'yes'">
<xsl:attribute name="index"><xsl:value-of select="$index"/></xsl:attribute>
</xsl:if><xsl:value-of select="normalize-space($fn-text)"/></fn>
</xsl:when>
<xsl:otherwise>
<fnref linkend="{$idref-target}">
<xsl:if test="$debug = 'yes'">
<xsl:attribute name="index"><xsl:value-of select="$index"/></xsl:attribute>
</xsl:if>
</fnref>
</xsl:otherwise>
</xsl:choose>
</xsl:template>我还必须考虑多个表的可能性,所以我正在测试超级节点是否具有相同的父节点。我想知道这在键的定义中是否会更有效率?
此外,出于调试的目的,我维护了原始索引,并创建了新的id属性。最后,我没有使用单独的匹配模式,而是只有一个sup模板,并在其中使用了一个<xsl:choose>分支来测试这是<sup>的第一个实例还是后续实例
https://stackoverflow.com/questions/62410448
复制相似问题