Search code examples
xmlxsltxslt-3.0tei

XSL: add a link to a substring within a string made of several TEI-XML elements


Since few days, I try to add a link to substring w[@type='verb'] within a string. I am working on a TEI-XML transliteration of clay tablets, thus elements and @type of <w> contained in <l> are not always in the same order.

XSLT version 3.0:

<?xml version="1.0" encoding="UTF-8"?>

<xsl:template match="/">
 <xsl:apply-templates select="//div1"/>
</xsl:template>

<xsl:template match="//div1">
<!-- additional content before <ul> -->
 <ul>
  <li>
    <xsl:for-each select="descendant-or-self::lg/l[@n]">
       <xsl:variable name="verb1" select="w[@type='verb']"/>
       <xsl:variable name="href1" select="w[@type='verb']/@lemmaRef"/>
       <xsl:variable name="single-l" select="w[@type='coo'] | w[@type='noun'] | w[@type='verb'] | w[@type='num'] | w[@type='adv'] | w[@type='adj'] | g | name"/>

       <xsl:value-of select="$single-l"/> 
       <sup><xsl:value-of select="./@n"/></sup>
     </xsl:for-each>
   </li>
 </ul>
</xsl:template>

I need to add a link lemmaRef for each w[@type='verb'].

A sample of TEI — I removed @xml:id from element other than l for this example:

<lg>
    <l n="4b-5a" xml:id="ktu1-3_ii_l4b-5a">
       <w type="coo">w</w><space/>
       <w type="verb" lemmaRef="uga/verb.xsl#qry"><damage degree="medium" facs="definir"><supplied resp="KTU">t</supplied></damage>qry</w>
       <g>.</g>
       <w type="noun" lemmaRef="uga/noun.xsl#ġlm">ġlmm</w>
       <lb/><w>b</w><space/>
       <w type="noun" lemmaRef="uga/noun.xsl#št">št</w>
       <g>.</g>
       <w type="noun" lemmaRef="uga/noun.xsl#ġr">ġr</w>
       <g>.</g>
    </l>
 </lg>

I need to display:

<ul>
 <li>w <a href="uga/verb.xml#qry">tqry</a> . ġlmm št . ġr .<sup>4b-5a</sup></li>
</ul>

"tqry" is a verb contained in <l>.

How can I do in XSLT to be able to display <a href="{$href1}"><xsl:value-of select="$verb1"/>. I tried replace of $single-l or to define a new variable of the previous XSLT code, but it doesn't work. I have tried also with key but I think I still have a problem of undertanding...

In advance, thank you for your kind advice.


Solution

  • I don't think you should try to build a string and then to insert markup there, it seems it should be possible to simply process the child elements and then match on the lg/l[@n]/w[@type = 'verb'] to transform it to a HTML hyperlink:

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        exclude-result-prefixes="xs"
        version="3.0">
    
      <xsl:output method="html" indent="yes" html-version="5"/>
      <xsl:strip-space elements="*"/>
    
      <xsl:template match="/">
        <html>
          <head>
            <title>Example</title>
          </head>
          <xsl:apply-templates/>
        </html>
      </xsl:template>
    
      <xsl:template match="div">
          <section>
              <ul>
                  <xsl:apply-templates select=".//lg/l[@n]"/>
              </ul>
          </section>
      </xsl:template>
    
      <xsl:template match="lg/l[@n]">
          <li>
              <xsl:apply-templates/>
              <sup>
                  <xsl:value-of select="@n"/>
              </sup>
          </li>
      </xsl:template>
    
      <xsl:template match="lg/l[@n]/w[@type = 'verb']">
          <a href="{@lemmaRef}">
              <xsl:apply-templates/>
          </a>
      </xsl:template>
    
      <xsl:template match="space">
          <xsl:text> </xsl:text>
      </xsl:template>
    
    </xsl:stylesheet>
    

    This currently does not quite produce the wanted result but

    <li>w <a href="uga/verb.xsl#qry">tqry</a>.ġlmmb št.ġr.<sup>4b-5a</sup></li>
    

    instead but if there is content from an element you don't need or want you can add an empty template for that so that it doesn't produce any output (e.g. <xsl:template match="lg/l[@n]/w[not(@type)]"/>).

    I am not sure whether there is also important white space missing and what are the rules to insert it, you might need to explain that.

    Online sample is at http://xsltfiddle.liberty-development.net/b4GWV5/1.