简体   繁体   English

如何使用XSLT / XSL-FO抑制相同的脚注?

[英]How can I suppress identical footnotes with XSLT/XSL-FO?

First of all, I'm trying to create a PDF from an XML with help of XSLT, XPath and XSL-FO. 首先,我试图借助XSLT,XPath和XSL-FO从XML创建PDF。

I have an XML with multiple footnotes and I use a template to render them automatically after tag name "note". 我有一个带有多个脚注的XML,我使用模板在标记名称“note”后自动呈现它们。

XML: XML:

<document>  
  <ul type='custom-list-1' startdist="0.5cm" gap="0.15cm">
    <li space-before="30pt">
        List-item 1
        <block margin-left="-15pt" margin-right="-15pt" text-align="center">
            <table layout="fixed" width="100%">
                <col number="1" width="30%" />
                <col number="2" width="17%" />
                <col number="3" width="17%" />
                <col number="4" width="17%" />
                <col number="5" width="17%" />                      
                <tbody>
                    <tr font-style="italic">
                        <th>sample title</th>
                        <th colspan="4">sample title</th>
                    </tr>                       
                    <tr>
                        <td>
                            Bla bla bla
                            <note name="name-1">
                                Footnote for "bla bla bla"
                            </note>
                        </td>
                        <td colspan="4">
                            .............
                        </td>
                    </tr>                   
                    <tr>
                        <td>
                            Comision Administrare Online Banking
                        </td>
                        <td colspan="4">
                            .........
                        </td>
                    </tr>
                    <tr>
                        <td>
                            Another... Bla bla bla
                            <note name="name-2">
                                Footnote for "Another... Bbla bla bla"
                            </note>
                        </td>
                        <td colspan="4">
                            ......
                        </td>
                    </tr>                       
                </tbody>                
            </table>                            
        </block>
    </li>
    <li space-before="30pt">List-item 2:        

        <block margin-left="-15pt" text-align="center">
            <table layout="fixed" width="100%">
                <col number="1" width="18%" />
                <col number="2" width="13%" />
                <col number="3" width="13%" />
                <col number="4" width="16%" />                  
                <col number="5" width="13%" />
                <col number="6" width="13%" />
                <col number="7" width="13%" />
                <tbody>
                    <tr font-style="italic">
                        <th colspan="2" rowspan="2">Sample title</th>
                        <th colspan="2">Sample title</th>                       
                        <th rowspan="2">Sample title</th>
                        <th rowspan="2">Sample title</th>
                        <th rowspan="2">Sample title</th>
                    </tr>
                    <tr font-style="italic">
                        <th>Min</th>
                        <th>Max</th>
                    </tr>                       
                    <tr>                            
                        <td colspan="2">Some text here</td>
                        <td colspan="2">
                            1%
                            <note name="name-3">
                                Footnote for "1%"
                            </note>
                            / 0.5%
                            <note name="name-4">
                                Footnote for "0.5%"
                            </note>
                        </td>
                        <td>-</td>
                        <td>-</td>
                        <td>-</td>                          
                    </tr>                       
                    <tr>                            
                        <td colspan="2">Sample text</td>
                        <td colspan="2">
                            1%
                            <note name="name-3">
                                Footnote for "1%"
                            </note>
                            / 0.5%
                            <note name="name-4">
                                Footnote for "0.5%"
                            </note>
                        </td>
                        <td>-</td>
                        <td>-</td>
                        <td>-</td>                          
                    </tr>                       
                    <tr>                            
                        <td colspan="2">Sample text</td>
                        <td colspan="2">
                            1%
                            <note name="name-3">
                                Footnote for "1%"
                            </note>
                            / 0.5%
                            <note name="name-4">
                                Footnote for "0.5%"
                            </note>
                        </td>
                        <td>-</td>
                        <td>-</td>
                        <td>-</td>                          
                    </tr>                       
                </tbody>
            </table>
        </block>
    </li>
    <li space-before="30pt">List-item 3
        <block margin-left="-15pt" text-align="center">
            <table layout="fixed" width="100%">
                <col number="1" width="25%" />
                <col number="2" width="15%" />
                <col number="3" width="15%" />
                <col number="4" width="22%" />
                <col number="5" width="22%" />                      
                <tbody>
                    <tr font-style="italic">
                        <th colspan="2">Sample title</th>
                        <th></th>
                        <th>Sample title</th>
                        <th>Sample title</th>
                    </tr>
                    <tr>                            
                        <td colspan="2">Sample text</td>                            
                        <td></td>
                        <td>0%</td>
                        <td>0%</td>
                    </tr>
                    <tr>                            
                        <td colspan="2">Sample text</td>                            
                        <td></td>
                        <td>0.05%<note name="name-5">Footnote for "0.05%"</note></td>
                        <td>0.05%</td>
                    </tr>                       
                    <tr>                            
                        <td colspan="2">Sample text</td>                            
                        <td></td>
                        <td>0%</td>
                        <td>0%</td>
                    </tr>
                </tbody>
            </table>

        </block>
    </li>       
</ul>

XSLT: XSLT:

<xsl:attribute-set name="note.data" >
    <xsl:attribute name="text-align">justify</xsl:attribute>        
    <xsl:attribute name="font-weight">normal</xsl:attribute>
</xsl:attribute-set>

<xsl:key name="by-name" match="//note[@name]" use="@name" />

<xsl:template match="note">
    <xsl:call-template name="note" />
</xsl:template>

<xsl:template name="note">
    <xsl:param name="unique-elements" 
       select="current()[generate-id(.) = generate-id(key('by-name', @name)[1])]"/>     
    <xsl:param name="identical-elements" 
       select="current()[not(generate-id(.) = generate-id(key('by-name', @name)[1]))]"/>

    <xsl:if test="$unique-elements">
        <xsl:variable name="element" select="$unique-elements"/>

        <fo:footnote>       
            <fo:inline baseline-shift="super" font-size="75%" color="red">
                <xsl:number level="any" count="//note[generate-id(.) = generate-id(key('by-name', @name)[1])]" format="(1)" />
            </fo:inline>

            <fo:footnote-body xsl:use-attribute-sets="note.data">   
                <fo:block color="blue">                             
                    <fo:inline baseline-shift="super" font-size="75%">
                        <xsl:number level="any" count="//note[generate-id(.) = generate-id(key('by-name', @name)[1])]" format="(1)" />
                    </fo:inline>
                    <xsl:value-of select="$element" />                                              
                </fo:block>
            </fo:footnote-body>
        </fo:footnote>          
    </xsl:if>           

    <xsl:if test="$identical-elements">
        <fo:inline baseline-shift="super" font-size="75%" color="green">
            <xsl:number level="any" count="//note[generate-id(.) = generate-id(key('by-name', @name)[1])]" format="(1)" />
        </fo:inline>            
    </xsl:if>
</xsl:template>

PDF output: PDF输出:

在此输入图像描述

So, I managed to suppress the identical footnotes and maintain the count of the unique footnotes (in image colored with red) and add the last count value for the identical footnotes (in image colored with green). 因此,我设法抑制相同的脚注并保持独特脚注的数量(用红色着色的图像)并添加相同脚注的最后计数值(用绿色着色的图像)。

The problem now is that I can't figure it out how can I maintain the same count value for the identical footnotes. 现在的问题是我无法弄清楚如何为相同的脚注保持相同的计数值。

Thanks in advance! 提前致谢!

The best way would be to group the identical notes and then select the first one from each group. 最好的方法是将相同的注释分组,然后从每个组中选择第一个。 With XSLT 2.0 you can use the group-by atribute. 使用XSLT 2.0,您可以使用group-by属性。 In XSLT 1.0 you can do this creating a key for all notes: 在XSLT 1.0中,您可以为所有注释创建一个键:

<xsl:key name="notes" match="//note" use="@name"/>

And then calling your template using the predicate shown below: 然后使用下面显示的谓词调用您的模板:

<xsl:template match="parent-element">
...
     <xsl:apply-templates select="note[generate-id(.) = generate-id( key('notes', @name)[1])]" />
...
</xsl:template>

The expression compares the current note ( . ) with the first item in the group of note s with the same @name , so you are selecting the first item of each group. 表达式将当前note. )与具有相同@namenote组中的第一项进行比较,因此您选择每个组的第一项。

You will also have to fix your node-count and restrict it to the reduced set (since it is counting all nodes including the duplicate ones): 您还必须修复节点计数并将其限制为简化集(因为它计算所有节点,包括重复节点):

note[generate-id(.) = generate-id( key('notes', @name)[1])]

So here is a solution, but without using xsl:number, that usually gives me too much of a headache, but since you have been using level="any" it doesn't really matter: 所以这是一个解决方案,但是没有使用xsl:number,这通常让我头疼,但是因为你一直在使用level =“any”,所以这并不重要:

<xsl:template match="note">
    <!-- 
        counts unique preceding notes starting from first note with current @name
    -->
    <xsl:variable name="number"
        select="count((//note[@name=current()/@name])[1]/preceding::note[not(@name=../preceding::note/@name)]) + 1"/>

    <xsl:choose>
        <!-- if there is no preceding note with same name -->
        <xsl:when test="not(preceding::note/@name=current()/@name)">
            <fo:footnote>
                <fo:inline baseline-shift="super" font-size="75%" color="red">(<xsl:value-of
                        select="$number"/>)</fo:inline>

                <fo:footnote-body>
                    <fo:block color="blue">
                        <xsl:if test="@margin-left">
                            <xsl:attribute name="margin-left">
                                <xsl:value-of select="@margin-left"/>
                            </xsl:attribute>
                        </xsl:if>
                        <fo:inline baseline-shift="super" font-size="75%">(<xsl:value-of select="$number"
                            />)</fo:inline>
                        <xsl:value-of select="."/>
                    </fo:block>
                </fo:footnote-body>

            </fo:footnote>
        </xsl:when>
        <xsl:otherwise>
            <fo:inline baseline-shift="super" font-size="75%" color="red">(<xsl:value-of
                    select="$number"/>)</fo:inline>
        </xsl:otherwise>
    </xsl:choose>


</xsl:template>

If you are using AH Formatter, you can suppress duplicate footnotes on the same page by using the aptly named axf:suppress-duplicate-footnote extension property. 如果您使用的是AH Formatter,则可以使用恰当命名的axf:suppress-duplicate-footnote扩展属性来抑制同一页面上的axf:suppress-duplicate-footnote See https://www.antennahouse.com/product/ahf64/ahf-ext.html#axf.suppress-duplicate-footnote and the "Footnote arrangement in the column document (axf:footnote-position)" sample from https://www.antennahouse.com/antenna1/comprehensive-xsl-fo-tutorials-and-samples-collection/ 请参阅https://www.antennahouse.com/product/ahf64/ahf-ext.html#axf.suppress-duplicate-footnotehttps:/中的“列文档中的脚注排列(axf:脚注位置)”示例/www.antennahouse.com/antenna1/comprehensive-xsl-fo-tutorials-and-samples-collection/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM