XSL: Match ID and IDREFS

I have problem with resolving ID and IDREFS linking and below is my input as well as XSL and corresponding output

input XML doc:
<root>
<p>These afferent fibres project <link rid="r1">1</link> to the dorsal horn of the spinal cord where they synapse on neurons <link rid="r1">1</link> projecting to higher .... to the dorsal horn of the spinal cord where they synapse to the dorsal horn of the spinal cord <link rid="r2">2</link> where they synapse</p>
<ftn id="r1">First footnote</ftn>
<ftn id="r2">Second footnote</ftn>
</root>

current xsl:

<xsl:key name="key1" match="ftn" use="@id"/>

<xsl:template match="p">
<text:p><xsl:apply-templates /></text:p>
</xsl:template>

<xsl:template match="link">
<xsl:apply-templates select="key('key1', @refid)"/>
</xsl:template>

<xsl:template match="ftn">
<text:footnote><xsl:apply-templates /></text:footnote>
</xsl:template>

When I use the above XSL syntax all of the links are turned into respective footnotes. But I do want only for the first instances when key pattern matches. ie for the second <link rid="r1">1</link>, I just need content of link.

I tried count the key as count(key('key1',@refid)) =1 do something and if its value is greater just copy the value of  <link> but it is not working.

Pl shed your thoughts.


rshk2001Asked:
Who is Participating?
 
Geert BormansInformation ArchitectCommented:
You can easily do that by checking whether the link @rid in the current context is the first of that kind in the document
Using generate-id and a key is the most efficient way of doing so

I think this does what you want
<xsl:key name="key1" match="ftn" use="@id"/>
    <xsl:key name="link" match="link" use="@rid"/>
    
    <xsl:template match="p">
        <text:p><xsl:apply-templates /></text:p>
    </xsl:template>
    
    <xsl:template match="link">
        <xsl:choose>
            <xsl:when test="generate-id() = generate-id(key('link', @rid)[1])">
                <xsl:apply-templates select="key('key1', @rid)" mode="full"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:apply-templates select="key('key1', @rid)" mode="text"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    
    <xsl:template match="ftn" mode="full">
        <text:footnote><xsl:apply-templates /></text:footnote>
    </xsl:template>
    <xsl:template match="ftn">
        <text:footnote><xsl:apply-templates /></text:footnote>
    </xsl:template>
    <xsl:template match="ftn" mode="text">
        <xsl:apply-templates />
    </xsl:template>

Open in new window

0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.