Re: [xsl] REPOST - duplicate footnotes

Subject: Re: [xsl] REPOST - duplicate footnotes
From: Wendell Piez <wapiez@xxxxxxxxxxxxxxxx>
Date: Wed, 20 Sep 2006 11:30:58 -0400
Anne Marie,

Your diagnosis of the problem is correct, but in trying to solve it you are making it harder than it is.

First, consider whatever code you are using to number your footnotes:

<xsl:number count="footnote" format="1" level="any"/>

I take it this works well enough. The reason this works is because it generates a number *for the context node* (this is important) in relation to its position in the tree.

Now, when you process a different kind of element, the xrefinline, you want to generate a similar number, except you want the number generated not of the xrefinline itself, but of the footnote to which it points.

This would be something like

<xsl:for-each select="//footnote[@opid=$xrefnode]">
  <!-- changing context to the footnote being pointed to -->
  <xsl:number count="footnote" format="1" level="any"/>
  <!-- generating its number -->
</xsl:for-each>

Note that for either performance or maintenance reasons, you may find it worthwhile either to:

* bind //footnote to a global variable, as in

<xsl:variable name="footnotes" select="//footnote"/>

and then use it (for-each select="$footnotes[@opid=$xrefnode])

* or perhaps declare a key to grab footnotes using their @opid attributes (which will be even faster for the processor).

But the basic solution is the same.

Sometimes in complex stylesheets it's worthwhile creating an entire template mode for generating numbers this way:

<xsl:template match="footnote" mode="number">
  <xsl:number format="1" level="any"/>
  <!-- defaults to count="footnote" since we're matching a footnote -->
</xsl:template>

<xsl:template match="footnote">
  ...
  <!-- generate your number for the footnote -->
  <xsl:apply-templates select="." mode="number"/>
</xsl:template>

<xsl:template match="xrefinline">
  ...
  <!-- generate your number for the footnote being pointed to -->
  <xsl:apply-templates select="$footnotes[@opid=$xrefnode]" mode="number"/>
</xsl:template>

... but it's still the same solution. This is nice since if there's other formatting required, such as the <fo:inline>, you can also put that in the template where the number is generated.

Cheers,
Wendell

At 11:18 AM 9/20/2006, you wrote:
Hello XSL experts,

I'm reposting this question because I'm still thrashing trying to solve
this problem.

I have an XSL style sheet that counts all the footnotes in a document.
I'm trying to modify this stylesheet to not increment the count for
duplicate footnotes and to not output a footnote number with footnote
text for the duplicate note.

Desired output for this XML:

foo<footnote notetext="footnote text 1" opid="fn1"/>
bar<footnote notetext="footnote text 2" opid="fn2"/>
boo<xrefinline toFootnote="yes" targetid="opid="fn2"></xrefinline>

foo1
bar2
boo2

1. footnote text 1
2. footnot text 2

The xrefinline element has a targetid attribute set by a user to the
unique opid value of the footnote to reference. Here is the XSL template
for xrefinline.

When this template is matched, I have the opid number of the target
footnote.  I need to figure out how to output the number of the footnote
being referenced.  The code below always outputs 1, the number of
footnotes whose opid attribute equals the current targetid attribute.

Is there a way to do this?

<xsl:template match="xrefinline">
   <xsl:variable name="xrefnode" select="./@targetid" />

                <xsl:choose>
                        <xsl:when test="@toFootnote='no'">
                        <fo:basic-link color="blue"
internal-destination="{@targetid}">
                                <xsl:value-of select="."/>
(<xsl:value-of select="$__Page_Token"/>
                        <fo:page-number-citation
ref-id="{@targetid}"/>)</fo:basic-link>
                        </xsl:when>
                <xsl:otherwise>
                                <fo:inline baseline-shift="super"
font-size="8pt">
                                    <!--counts the number of footnotes
whose opid attribute = the targetid -->
                                        <!-- attribute of the current
note. I want to output the number of the  -->
                                        <!-- footnote referenced by this
targetid. -->
                                        <xsl:number
count="footnote[@opid=$xrefnode]" format="1" level="any"/>
                                </fo:inline>
            </xsl:otherwise>
                </xsl:choose>
   </xsl:template>

Current Thread