Reputation: 577
Using XSLT2 and given the following sort of file:
<refbody>
<p>That's line 1<fn>It does this</fn></p>
<b>That's line 2<fn>It does that</fn></b>
<div>
<p>That's line 3<fn>It does this</fn></p>
</div>
</refbody>
I would like create the following:
<refbody>
<p>That's line 1<fn id="123">It does this</fn></p>
<b>That's line 2<fn>It does that</fn></b>
<div>
<p>That's line 3<xref href="123"/></p>
</div>
</refbody>
So the idea is:
For each fn
tag, check if it has duplicates (i.e same text).
fn
by an xref
element and
use the reference's id in the href
attribute.These fn
elements can be in any level, grouped or not, their position is absolutely unpredictable.
I have tried the following so far:
<xsl:template match="fn">
<xsl:variable name="duplicated" select="//fn[text()=.]"/>
<xsl:choose>
<xsl:when test="count($duplicated) gt 1">
<xsl:choose>
<xsl:when test="not(preceding-sibling::fn[text()=.] or preceding::fn[text()=.])">
<fn id="{generate-id(.)}">
<xsl:value-of select="text()"/>
</fn>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="root" select="name(node()[1])"/>
<xsl:variable name="id" select="$duplicated[1]/@id"/>
<xref href="{$id}"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="."></xsl:copy-of>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
Obviously, I don't have access to the ID doing that, so this is not good.
Upvotes: 1
Views: 76
Reputation: 167506
Use a key to identify duplicates:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:key name="fn" match="fn" use="."/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* , node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="fn[. is key('fn', .)[1] and key('fn', .)[2]]">
<fn id="{generate-id()}">
<xsl:apply-templates/>
</fn>
</xsl:template>
<xsl:template match="fn[not(. is key('fn', .)[1])]">
<xref href="{generate-id(key('fn', .)[1])}"/>
</xsl:template>
</xsl:stylesheet>
Upvotes: 3