xsltgroupingxslt-2.0processing-instruction

matching the following and call template


This is a simplified XML which exposes the general structure of the problem I have.

<chapter num="07">
    <title>
        <page num="703"/>
        ... text (mixed content) ...
    </title>

    <page num="704"/>
    <section level="sect1">
        <title>...text...</title>
        <para num="7.1.1">... a lot of text (mixed content)...</para>
    </section>
    <section level="sect1">
        <title>... text... </title>
        <para num="7.2.1">Some text...
            <footnoteref linkend="fn3" num="3"/>
            <footnote num="3" id="fn3"> ... mixed content ...</footnote> 
            ...more text...
        </para>

        <page num="705"/>
        <section level="sect2">
            <title>...</title>
            <para num="7.2.2">... text ...
                <footnoteref linkend="fn4" num="4"/>
                <footnote num="4" id="fn4">...</footnote> 
                ... more text ...
                <footnoteref linkend="fn5" num="5"/>
                <footnote num="5" id="fn5">...</footnote> 
                ... more text ...
            </para>
            <para num="7.2.5">...

                <page num="706"/>... 

                <footnoteref linkend="fn6" num="6"/>
                <footnote num="6" id="fn6"> ... </footnote>
            </para>
            <para num="7.2.6">... some text
                <footnoteref linkend="fn7" num="7"/>
                <footnote num="7" id="fn7"> ... </footnote>  
            </para>
        </section>
    </section>
</chapter>

I have to place one processing instruction <?pb label='page number'?> before the first <footnote> matching the last preceding <page>. It should appear only once and the page number should be the same as the value in the num attribute of the last <page> element that appeared.

For example, if I process the source above, I expect to generate in my result document one <?pb label='704'?> immediately before <footnote num="3">, one <?pb label='705'?> immediately before <footnote num="4"> (grouping footnotes 4 and 5), and one <?pb label='706'?> immediately before <footnote num="6"> (grouping footnotes 6 and 7). There is a template to process the <footnote> elements and they are placed together at the end of each page, preceded by the processing instruction (the <footnoteref> elements stay where they are).

My XSL is here. Since it is too big, I'm unable to paste it here.

I'm getting duplicates in the footnote processing instructions (the pb labels). There should be a pblabel only before the first footnote following the last page tag. I tried matching with preceding::page but it didn't work. The the same processing instruction is being repeated multiple times. For example: <?pb label='706'?> should appear only once above footnote 6 because it is the first footnote following page 706.


Solution

  • It's hard to tell without doing a time consuming analysis, but try changing this xsl:if (in match="footnote" mode="footnote"):

        <xsl:if test="preceding::node()[page[1]]">
            <xsl:variable name="op">&#60;</xsl:variable>
            <xsl:variable name="apos">'</xsl:variable>
            <xsl:variable name="cl">&#62;</xsl:variable>
    
            <xsl:value-of select="concat($op,'?pb label=',$apos,preceding::page[1]/@num,$apos,'?',$cl)"/>
    
        </xsl:if>
    

    To this:

        <xsl:if test="(preceding::page|preceding::footnote)[last()][self::page]">
            <xsl:processing-instruction name="pb" select="concat('label=''',preceding::page[1]/@num,'''?')"/>
        </xsl:if>
    

    Kinda strange that you're trying to output XML processing instructions when your output method is HTML (which would have SGML processing instructions).