I would like to give cross-links in the below XML using XSLT 3.0.
My Input XML is:
<?xml version="1.0"?>
<book id="bk1">
<p>The heterogeneity of patients, various clinical manifestations and the dynamics of CS development cause problems **[1]** with identifying its unified definition. However, CS can be usually diagnosed on the basis of clinical criteria which are easy to assess without the need for advanced hemodynamic monitoring **[6, 9, 12]**. Increasing knowledge about **[8, 11-14, 17]** patient characteristics and better understanding of the CS pathophysiology.</p>
</book>
My Expected XML is:
<?xml version="1.0"?>
<book id="bk1">
<p>The heterogeneity of patients, various clinical manifestations and the dynamics of CS development cause problems **[<a href="#bib1">1</a>]** with identifying its unified definition. However, CS can be usually diagnosed on the basis of clinical criteria which are easy to assess without the need for advanced hemodynamic monitoring **[<a href="#bib6">6</a>, <a href="#bib9">9</a>, <a href="#bib12">12</a>]**. Increasing knowledge about **[<a href="#bib8">8</a>, <a href="#bib11">11</a><a href="#bib12"></a><a href="#bib13"></a>-<a href="#bib14">14</a>, <a href="#bib17">17</a>]** patient characteristics and better understanding of the CS pathophysiology.</p>
</book>
My XSLT look like below:
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" exclude-result-prefixes="#all"> <xsl:output method="xhtml" /> <xsl:template match="/|node()|*|@*"> <xsl:copy> <xsl:apply-templates select="node()|*|@*" /> </xsl:copy> </xsl:template> <xsl:param name="para-rgxp"> <text-patterns> <bibnosingle>\[(\d )\]</bibnosingle> <bibunnumber>(\p{Lu}[\p{L}-] )( et al.?)\s \(([0-9]{4})\)</bibunnumber> <bibnomultiline>\[(\d ),\s (\d )</bibnomultiline> </text-patterns> </xsl:param> <xsl:template match="div[not(preceding-sibling::*[matches(.,'^References')])]/text()" priority="10"> <xsl:analyze-string select="." regex="{string-join($para-rgxp/text-patterns/*,'|')}"> <xsl:matching-substring> <xsl:choose> <xsl:when test="matches(.,$para-rgxp/text-patterns/bibnosingle)" > <a href="#bib{regex-group(1)}"> <xsl:value-of select="."/> </a> </xsl:when> <xsl:when test="matches(.,$para-rgxp/text-patterns/bibunnumber)" > <a href="#bib{regex-group(2)}"> <xsl:value-of select="."/> </a> </xsl:when> <xsl:when test="matches(.,$para-rgxp/text-patterns/bibnomultiline)" > <a href="#bib{regex-group(3)}{regex-group(4)}"> <xsl:value-of select="."/> </a> </xsl:when> <xsl:otherwise> <xsl:value-of select="."/> </xsl:otherwise> </xsl:choose> </xsl:matching-substring> <xsl:non-matching-substring> <xsl:value-of select="."/> </xsl:non-matching-substring> </xsl:analyze-string> </xsl:template>
[1]
is working fine, but [6, 9, 12]
and [8, 11-14, 17]
is not working. How to get expected result? But [6, 9, 12] and [8, 11-14, 17] should be convert to [6, 9, 12] and [8, 11-14, 17]. But this is not converting. How to get the expect result through using XSLT 3.0.
CodePudding user response:
I think to identify the bracketed number references you can use a pattern, it might then be sufficient to process its content with two tokenize
calls:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:param name="num-ref-pattern" as="xs:string" expand-text="no">\[([0-9] (-[0-9] )?(,\s*[0-9] (-[0-9] )?)*)\]</xsl:param>
<xsl:template match="p//text()">
<xsl:apply-templates select="analyze-string(., $num-ref-pattern)" mode="num-refs"/>
</xsl:template>
<xsl:template mode="num-refs" match="fn:group[@nr = 1]">
<xsl:for-each select="tokenize(., ',\s*')">
<xsl:if test="position() gt 1">, </xsl:if>
<xsl:for-each select="let $refs := tokenize(., '-') return if ($refs[2]) then xs:integer($refs[1]) to xs:integer($refs[2]) else xs:integer($refs[1])">
<a href="#bib{.}">{.}</a>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
<xsl:output method="html" indent="no" html-version="5"/>
<xsl:mode on-no-match="shallow-copy"/>
</xsl:stylesheet>
Result e.g.
<book id="bk1">
<p>The heterogeneity of patients, various clinical manifestations and the dynamics of CS development cause problems **[<a href="#bib1">1</a>]** with identifying its unified definition. However, CS can be usually diagnosed on the basis of clinical criteria which are easy to assess without the need for advanced hemodynamic monitoring **[<a href="#bib6">6</a>, <a href="#bib9">9</a>, <a href="#bib12">12</a>]**. Increasing knowledge about **[<a href="#bib8">8</a>, <a href="#bib11">11</a><a href="#bib12">12</a><a href="#bib13">13</a><a href="#bib14">14</a>, <a href="#bib17">17</a>]** patient characteristics and better understanding of the CS pathophysiology.</p>
</book>