Xslt 转换';排版';docbook样式的脚注

Xslt 转换';排版';docbook样式的脚注,xslt,docbook,Xslt,Docbook,我有一堆包含calstables的内容,其中脚注是使用排版技术完成的,每个索引都使用元素进行设置,每个脚注都包含在表格末尾的跨行中 我想将它们转换为使用Docbook脚注标记,如和 示例数据如下(我添加了和元素,以显示它来自何处以及需要转到何处) 项目 项目a 项目B1 条目1 60 3.2 条目A 150 3.552 此条目 2603 3.552 1拉特 2项价值24.5米。另见下文注释。 3坡道上升19.8米。 项目 项目a 项布拉特 条目1 60 3.2 条目A 150 3.55项目价值

我有一堆包含calstables的内容,其中脚注是使用排版技术完成的,每个索引都使用
元素进行设置,每个脚注都包含在表格末尾的跨行中

我想将它们转换为使用Docbook脚注标记,如和

示例数据如下(我添加了
元素,以显示它来自何处以及需要转到何处)


项目
项目a
项目B1
条目1
60
3.2
条目A
150
3.552
此条目
2603
3.552
1拉特
2项价值24.5米。另见下文注释。
3坡道上升19.8米。
项目
项目a
项布拉特
条目1
60
3.2
条目A
150
3.55项目价值24.5米。另见下文注释。
此条目
260上升19.8米。
3.55
这一逻辑相当简单明了:

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
1。将所有内容复制到输出,除非。。。
2.它包含一个``元素,在这种情况下
1.如果它具有“@nameend”属性,则不执行任何操作,或者
2.如果它是此索引的第一个实例,请创建一个具有“@id”属性的脚注元素,从匹配的跨行获取内容,或者
3.如果不是第一个实例,请创建一个footnoteref元素,该元素具有匹配的“@linkend”属性
当然也有很多错误检查,但我现在不太担心

我可以使用一组单独的匹配模式来处理上面的#2,如

<xsl:template match="sup[text() = '1'][1]">
<xsl:template match="sup[text() = '2'][1]">
<xsl:template match="sup[text() = '3'][1]">

但我认为必须有一种更优雅的匹配模式(可能使用键?)来匹配所使用的每个索引的第一个实例,但就我而言,我无法想象它可能是什么

到目前为止,我已经定义了两个键

<xsl:key name="fn-indices" match="sup" use="number(.)"/>
<xsl:key name="fn-text" match="entry[sup][@nameend &gt; @namest]" use="number(sup)"/>

但我不知道如何最好地使用它们

对每个索引的第一个实例的优雅匹配模式有何建议?

sup[.is key('fn-indexs',number())[1]
应匹配每个“组”中的第一个项目,以便您能够替换

<xsl:template match="sup[text() = '1'][1]">
<xsl:template match="sup[text() = '2'][1]">
<xsl:template match="sup[text() = '3'][1]">



操作员检查节点标识。

因此我提出了这个模板,它似乎满足了我的需要

注意:我将
footnote
缩短为
fn
并将
footnoteref
缩短为
fnref
,以避免目前与其他流程发生冲突

另外,我没有使用is而是使用了1.0兼容的
generate-id()
,但我可能会在适当的时候对此进行更改

<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>

我还必须考虑多个表的可能性,因此我正在测试sup节点是否具有相同的父节点。我想知道这在关键定义中是否更有效

此外,为了调试目的,我还维护了原始索引,并创建了新的
id
属性
最后,我没有使用单独的匹配模式,而是使用了一个
sup
模板,并在其中使用了一个
分支来测试这是否是

的第一个或后续实例,是XSLT 1还是2/3?它是V2,正在使用Saxon/OxygenXMLI不熟悉“is”操作符?@FeargalHogan,XPath规范都是在线的,所以请尽量让自己熟悉。
<xsl:template match="sup[. is key('fn-indices', number())[1]]">
<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>