I have some source XML that contains cross-references to multiple values within one attribute. I need to separate these into their own distinct elements with attribute values.
Input XML:
<code><p>Blah blah blah <xref ref-type="bibr" rid="ref004 ref005 ref006 ref007">4–7</xref>.</p>
</code>
<code><p>Blah blah blah <xref ref-type="bibr" rid="ref004 ref005 ref006 ref007">4–7</xref>.</p>
</code>
<p>Blah blah blah <xref ref-type="bibr" rid="ref004 ref005 ref006 ref007">4–7</xref>.</p>
Desired Output XML:
<code><p>Blah blah blah <xref ref-type="bibr" rid="ref004 ref005 ref006 ref007">4</xref><xref
ref-type="bibr" rid="ref005"/><xref ref-type="bibr" rid="ref006"/>–<xref
ref-type="bibr" rid="ref007">7</xref>.</p>
</code>
<code><p>Blah blah blah <xref ref-type="bibr" rid="ref004 ref005 ref006 ref007">4</xref><xref
ref-type="bibr" rid="ref005"/><xref ref-type="bibr" rid="ref006"/>–<xref
ref-type="bibr" rid="ref007">7</xref>.</p>
</code>
<p>Blah blah blah <xref ref-type="bibr" rid="ref004 ref005 ref006 ref007">4</xref><xref
ref-type="bibr" rid="ref005"/><xref ref-type="bibr" rid="ref006"/>–<xref
ref-type="bibr" rid="ref007">7</xref>.</p>
Notice the 2 cross-references in the middle become empty elements.
I have the following XSLT but it’s not getting me the correct output – it’s inserting the attribute values as element content.
<code><xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="xref">
<xsl:variable name="rid" select="@rid"/>
<xsl:choose>
<xsl:when test="contains($rid, ' ')">
<!-- Multiple references -->
<xsl:variable name="refs" select="tokenize($rid, ' ')"/>
<xsl:for-each select="$refs">
<xsl:if test="position() > 1">
<xsl:text> </xsl:text>
</xsl:if>
<xsl:variable name="refNum" select="substring-after(., 'ref')"/>
<xsl:element name="xref">
<xsl:attribute name="ref-type">bibr</xsl:attribute>
<xsl:attribute name="rid">
<xsl:value-of select="concat('ref', $refNum)"/>
</xsl:attribute>
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<!-- Single reference -->
<xsl:element name="xref">
<xsl:attribute name="ref-type">bibr</xsl:attribute>
<xsl:attribute name="rid">
<xsl:value-of select="$rid"/>
</xsl:attribute>
<xsl:value-of select="."/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</code>
<code><xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="xref">
<xsl:variable name="rid" select="@rid"/>
<xsl:choose>
<xsl:when test="contains($rid, ' ')">
<!-- Multiple references -->
<xsl:variable name="refs" select="tokenize($rid, ' ')"/>
<xsl:for-each select="$refs">
<xsl:if test="position() > 1">
<xsl:text> </xsl:text>
</xsl:if>
<xsl:variable name="refNum" select="substring-after(., 'ref')"/>
<xsl:element name="xref">
<xsl:attribute name="ref-type">bibr</xsl:attribute>
<xsl:attribute name="rid">
<xsl:value-of select="concat('ref', $refNum)"/>
</xsl:attribute>
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<!-- Single reference -->
<xsl:element name="xref">
<xsl:attribute name="ref-type">bibr</xsl:attribute>
<xsl:attribute name="rid">
<xsl:value-of select="$rid"/>
</xsl:attribute>
<xsl:value-of select="."/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</code>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="xref">
<xsl:variable name="rid" select="@rid"/>
<xsl:choose>
<xsl:when test="contains($rid, ' ')">
<!-- Multiple references -->
<xsl:variable name="refs" select="tokenize($rid, ' ')"/>
<xsl:for-each select="$refs">
<xsl:if test="position() > 1">
<xsl:text> </xsl:text>
</xsl:if>
<xsl:variable name="refNum" select="substring-after(., 'ref')"/>
<xsl:element name="xref">
<xsl:attribute name="ref-type">bibr</xsl:attribute>
<xsl:attribute name="rid">
<xsl:value-of select="concat('ref', $refNum)"/>
</xsl:attribute>
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<!-- Single reference -->
<xsl:element name="xref">
<xsl:attribute name="ref-type">bibr</xsl:attribute>
<xsl:attribute name="rid">
<xsl:value-of select="$rid"/>
</xsl:attribute>
<xsl:value-of select="."/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>