Search code examples
xslttei

xsl: when two nodes are equal, display child of first node


I'm using XML Editor 19.1, Saxon P.E 9.7.

For each selected div, I'm looking to display a graphic/@url, following each <surface> if surface/@xml:id = div/@facs.

XSL

 <xsl:for-each select="descendant-or-self::div3[@type='col']/div4[@n]">
  <xsl:variable name="div4tablet" select="@facs"/>
   <xsl:choose>
    <xsl:when test="translate(.[@n]/$div4tablet, '#', '') = preceding::facsimile/surfaceGrp[@type='tablet']/surface[@n]/@xml:id">
     <xsl:value-of select=""/> <!-- DISPLAY graphic/@url that follows facsimile/surfaceGrp/surface -->
    </xsl:when>
    <xsl:otherwise/>
   </xsl:choose>
  [....]
 </xsl:for-each> 

TEI example

 <facsimile>     
  <surfaceGrp n="1" type="tablet">
   <surface n="1.1" xml:id="ktu1-2_i_1_to_10_img">
    <graphic url="../img/KTU-1-2-1-10-recto.jpg"/>
    <zone xml:id=""/>
    <zone xml:id=""/>
   </surface>
    <surface n="1.2" xml:id="ktu1-2_i_10_to_30_img">
    <graphic url="../img/KTU-1-2-10-30-recto.jpg"/>
    <zone xml:id=""/>
   </surface>
   [...]
  </surfaceGrp>
  <surfaceGrp n="2">
  [...]
  </surfaceGrp>
 </facsimile>


 <text>
  [...]
  <div3 type="col">
   <div4 n="1.2.1-10" xml:id="ktu1-2_i_1_to_10" facs="#ktu1-2_i_1_to_10_img">
    [...]
   </div4>
   <div4 n="1.2.10-30" xml:id="ktu1-2_i_10_to_30" facs="#ktu1-2_i_10_to_30_img">
    [...]
   </div4>
  </div3>
 </text> 

I have tried <xsl:value-of select="preceding::facsimile/surfaceGrp[@type='tablet']/surface[@n, @xml:id]/graphic/@url"/>, but it displays all graphic/@url and not only the one that follows fascsimile/surfaceGrp/surface. So my question: how to display only surface/graphic/@url for each div3[@type='col']/div4[@n]?

In advance, thank you for your kind help.


Solution

  • As you use XSLT 2 or 3 and the elements have the xml:id attribute you do not even need a key but can use the id function:

      <xsl:template match="div4">
          <div>
              <xsl:value-of select="id(substring(@facs, 2))/graphic/@url"/>
          </div>
      </xsl:template>
    

    I put the use of id into a template matching the div4 element but you can of course use it the same way inside of your for-each selecting those elements.

    See a minimal but complete sample at https://xsltfiddle.liberty-development.net/bdxtpR.