Search code examples
xmlxsltxslt-3.0tei

Display only if two TEI attributes values are equal


I have aTEI file with two sections, one for transcription, one for translation. In my transcription section, I have <div4 @xml:id="">, and I want to display descendant-or-self of <div2 @ana=""> of the translation section, only if <div4 @xml:id=""> = //<div2 @ana="">. I have made a <table>. Each section content is in a <td>.

TEI:

 <teiCorpus xmlns="http://www.tei-c.org/ns/1.0">
  <text xml:id="KTU1"> 
  <body>
   <div1 type="transcription"> 
    <div2 type="tablet" xml:id="ktu1-3"> <!-- an example of a tablet -->
    <head>Cycle of Baʿlu: KTU 1.3 recto</head>       
     <div3 type="col">    <!-- an example of a column's tablet -->
      <div4 n="1" xml:id="ktu1-3_ii_l1_to_4a">
       <head>Palace of ʿAnatu: combat readiness</head>
       <lg>
        <l n="0" xml:id="ktu1-3_ii_l0"><gap extent="unknown" reason="lost" unit="line"><desc>About 25 lines missing</desc></gap>
        </l>
        <l n="1" xml:id="ktu1-3_ii_l1">
         <w type="unknown">n</w><gap extent="unknown" reason="lost" confidence="1" unit="chars" quantity="6"/>[xxxxxxxxx]<w type="unknown">š</w>[xxx]
       </l>
       <l n="2-3a" xml:id="ktu1-3_ii_l2-3a">
        <w type="noun" lemmaRef="uga/noun.xml#kpr">kpr</w>
        <g>.</g>
        <w type="num">šbʿ</w>
        <g>.</g>
        <w type="noun" lemmaRef="uga/noun.xml#bnt">bnt</w>
        <g>.</g>
        <w type="noun" lemmaRef="uga/noun.xml#rḥ">rḥ</w>
        <g>.</g>
        <w type="noun" lemmaRef="uga/noun.xml#gmd">gdm</w>
        <lb/><w type="coo">w</w><space/>
        <w type="noun" lemmaRef="uga/noun.xml#anh">anhbm</w>
        <g>.</g>
       </l>
      </lg>  
      <!-- other <lg><l>...</l></lg> -->
     </div4>
     <div4 n="2" type="part" xml:id="ktu1-3_ii_l4b_to_16">
      <head>ʾAnatu is fighting in the valley</head>
       <lg>
        <l n="4b-5a" xml:id="ktu1-3_ii_l4b-5a" ana="#ktu1-3_ii_l4b-5a_int">
         <w type="coo">w</w><space/>
         <w type="verb" lemmaRef="../uga/verb.html#qry"><damage degree="medium" facs="definir"><supplied resp="KTU">t</supplied></damage>qry</w>
         <g>.</g>
         <w type="noun" lemmaRef="uga/noun.xml#ġlm" xml:id="ġlmm_4b-5a">ġlmm</w>
         <lb/><w type="prep">b</w><space/>
         <w type="noun" lemmaRef="uga/noun.xml#št">št</w>
         <g>.</g>
         <w type="noun" lemmaRef="uga/noun.xml#ġr">ġr</w>
         <g>.</g>
        </l>
       </lg>
      </div4>
      <!-- other <div4><head/><lg><l>...</l></lg> -->
     </div3>    
    </div2>
   </div1> 

   <div1 type="translation">
    <!-- here, translation of previous <div n="1"> -->
    <div2 n="1" ana="#ktu1-3_ii_l1_to_4a" xml:id="trans-ktu1-3_ii_l1_to_4a">
     <div3 n="0" ana="#ktu1-3_ii_l1">
      <entry>
       <interp xml:id="trans-VJ-ktu1-3_ii_l1">[Missing]</interp>
      </entry>
    </div3>
    <div3 n="1" ana="#ktu1-3_ii_l2-3a">
     <entry>
      <interp xml:id="trans-VJ-ktu1-3_ii_l2-3a">[translation impossible </interp>
     </entry>
    </div3>
    <div3 n="2-3a" ana="#ktu1-3_ii_l2-3a">
     <entry>
      <interp xml:id="trans-VJ-ktu1-3_ii_l2-3a">henna of seven tamarisks, scents of coriander and sea snail</interp>
     </entry>
    </div3>
    <!-- other div3 with content = <lg><l></l></lg> -->
   </div2>
   <div2 n="2" ana="#ktu1-3_ii_l4b_to_16" xml:id="trans-ktu1-3_ii_l4b_to_16">
    <div3 n="4b-5a" ana="#ktu1-3_ii_l4b-5a">
     <entry>
      <interp xml:id="trans-VJ-ktu1-3_ii_l4b-5a">and she met youths at the foot of the mountain</interp>
     </entry>
    </div3>
   <!-- other div3 with content = <lg><l></l></lg> -->
  </div2>
  <!-- other div2 for each translation of <div n=" "> -->
 </div1>
</body>
</text>
</teiCorpus>

XSLT (version 3.0)

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

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:tei="http://www.tei-c.org/ns/1.0"
xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
xmlns:array="http://www.w3.org/2005/xpath-functions/array"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xpath-default-namespace="http://www.tei-c.org/ns/1.0" 
exclude-result-prefixes="xs tei xsl math map array" version="3.0">

<xsl:output method="html" encoding="utf-8" indent="yes" html-version="5" doctype-system="about:legacy-compat"/>
<xsl:strip-space elements="*"/>

<xsl:mode on-no-match="shallow-copy"/>

<xsl:key name="div1" match="div1[@type]" use="@type"/>

<xsl:template match="/">
 <html>
        <head>
            <title/>
        </head>
        <body> 
             <div>
                 <h1>Transcription</h1>
                 <h2>KTU 1</h2> 
                 <xsl:apply-templates select="//div1"/>
             </div>
        </body> 
    </html>
</xsl:template>

<xsl:template match="div1">
 <xsl:for-each select="descendant-or-self::div3[@type='col']/div4[@n]">
  <table>
   <tr>
    <td>
     <xsl:variable name="div4-xml-id1" select="translate(self::div4[@n]/@xml:id, '_', ':')"/>
       <xsl:variable name="div4-xml-id2" select="replace($div4-xml-id1, '\-', '.')"/>
      <xsl:variable name="div4-xml-id3" select="replace($div4-xml-id2, '\Wto:', '-')"/>

      <xsl:value-of select="translate($div4-xml-id3, 'ktu', 'KTU')"/>               
      <xsl:text> - </xsl:text><xsl:value-of select="descendant-or-self::head"/> 
      <xsl:text>: </xsl:text>
     </td>
     <td style="padding-bottom: 10px; list-style-type : none;">
      <xsl:apply-templates select=".//lg/l[@n]"/>
     </td>

     <td>

       <!-- what I want to display in html but I cannot to it for each @xml:id of course -->
        <xsl:if test="./@xml:id='ktu1-3_ii_l1_to_4a'">
          <ul>
           <xsl:for-each select="//div2[@ana='#ktu1-3_ii_l1_to_4a']/div3/entry/interp">
            <li><xsl:value-of  select="."/></li>
           </xsl:for-each>
          </ul>
         </xsl:if>

         <xsl:if test="./@xml:id='ktu1-3_ii_l4b_to_16'">
           <ul>
             <xsl:for-each select="//div2[@ana='#ktu1-3_ii_l4b_to_16']/div3/entry/interp">  
              <li><xsl:value-of select="//div2[@ana='#ktu1-3_ii_l4b_to_16']"/></li>
             </xsl:for-each>
          </ul>
         </xsl:if>
        </td>
       </tr>
      </table>
     </xsl:for-each>
  </xsl:template>  

<!-- transcription section -->

<xsl:template match="lg/l[@n]">
    <li>
        <xsl:apply-templates/>
        <sup style="font-size: 0.8em">
            <xsl:value-of select="@n"/>
        </sup>
    </li>
</xsl:template>

<xsl:template match="lg/l[@n]/w">
    <xsl:if test="g">
        <xsl:value-of select="translate(descendant-or-self::g, '', ' ')"/>
    </xsl:if>
    <xsl:apply-templates />
</xsl:template>

<xsl:template match="lg/l/w[@type = 'verb']">
    <a href="{@lemmaRef}" name="{@xml:id}" id="verb">
        <!-- to remove white-space between character for <supplied>, <gap> -->
        <xsl:apply-templates select="translate(normalize-space(.), ' ', '')"/>
    </a>
 </xsl:template>
</xsl:stylesheet>

Since the TEI is a little bit complicated to read with several levels, I have also done a xlstfiddle of my TEI and XSLT: http://xsltfiddle.liberty-development.net/948Fn5c

So currently, the expected result for the translation section is correct:

 <td>
   <ul>
    <li>[Missing]</li>
    <li>[translation impossible]</li>
    <li>henna of seven tamarisks, scents of coriander and sea snail</li>
   </ul>
  </td>

  <td>
    <ul>
     <li>and she intercepts youths at the foot of the mountain</li>
    </ul>
  </td>

See print screen of expected (and actual) result: expected result

But of course, I cannot write for each <td> the values of each @xml:id and @ana. So instead of:

 <td>
    <xsl:if test="./@xml:id='ktu1-3_ii_l1_to_4a'">
      <ul>
       <xsl:for-each select="//div2[@ana='#ktu1-3_ii_l1_to_4a']/div3/entry/interp">
        <li><xsl:value-of  select="."/></li>
       </xsl:for-each>
      </ul>
    </xsl:if>

    <xsl:if test="./@xml:id='ktu1-3_ii_l4b_to_16'">
      <ul>
       <xsl:for-each select="//div2[@ana='#ktu1-3_ii_l4b_to_16']/div3/entry/interp">  
        <li><xsl:value-of select="//div2[@ana='#ktu1-3_ii_l4b_to_16']"/></li>
       </xsl:for-each>
      </ul>
    </xsl:if>
   </td>

I have tried:

   <ul>
      <li>
          <xsl:for-each select="//key('div1', 'translation')/div2">
            <xsl:if test="./substring(@ana, 2) = preceding::div4/@xml:id"/>
             <xsl:value-of select="."/>
          </xsl:for-each>
        </li>
    </ul>  

But the result is not good since it displays all <div2> for each <td> of the translation.

 <td>
   <ul>
     <li>[Missing][translation impossible]henna of seven tamarisks, scents of coriander and sea snail and she met youths at the foot of the mountain
     </li>
   </ul>
 </td>

Please apologize, it's not really easy to explain in good English all the steps, but I hope you will be able to understand what I'm trying to do.

Thanks again for your kind advice.


Solution

  • I think you do have a key set up that you can use to reference the translation in the right section:

                    <td> 
    
                      <xsl:variable name="referenced-div1" select="key('div1', 'translation')"/>
                      <xsl:variable name="referenced-translation" select="key('div2-trans', '#' || @xml:id, $referenced-div1)"/>
                        <ul>
                          <xsl:for-each select="$referenced-translation/div3/entry/interp">
                            <li><xsl:value-of  select="."/></li>
                          </xsl:for-each>
                        </ul>
                    </td>