Home > front end >  Numbered Reference Should be Cross-Link using XSLT
Numbered Reference Should be Cross-Link using XSLT

Time:11-30

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>
  • Related