htmlxsltxslt-1.0xslt-2.0marc

xslt get the immediate following sibling


I have the following:

 <root>
  <html>
   <table
    <tr> 
     <td width="1%" height="20"></td>
     <td width="18%">Book Location </td>
     <td width="81%">Technology (Applied sciences) Circulation</td>
    </tr>

I'm trying below xslt to get the immediate node content in which node content of td is "Book Location ":

<?xml version="1.0" encoding="utf-8"?>
 <xsl:stylesheet version="1.0"
 xmlns:marc="http://www.loc.gov/MARC21/slim"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text" indent="yes" />

 <xsl:template match="root">
  <xsl:for-each select="html">
  <xsl:text>START HERE</xsl:text>
  <xsl:text>&#13;&#10;</xsl:text>
  <xsl:text>=LDR  00000nam  2200000Ia 4500</xsl:text>
  <xsl:text>&#13;&#10;</xsl:text>

  <xsl:if test="//*[text()='Book Location ']">
   <xsl:text>=952  \\$cLocation: </xsl:text>
   <xsl:value-of select="following-sibling" />
  </xsl:if> 

  </xsl:for-each>

  </xsl:template>
 </xsl:stylesheet>

I'm not sure what to put in this part: Or if there's a better way to do it? Thanks in advance and have a nice day!


Solution

  • Your template suggests that you're thinking like a procedural language programmer. XSLT can be written more or less in that idiom, but it is not XSLT's natural idiom. Code written that way tends to be longer and messier than more natural code. In particular, although they have good uses, for-each elements usually carry a bit of code smell.

    This seems more natural to me, and it seems to work (but I had to test on a modified version of your input, since what you presented is not valid XML):

    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method="text" indent="yes" />
    
      <xsl:template match="/root/html">
        <xsl:text>START HERE</xsl:text>
        <xsl:text>&#13;&#10;</xsl:text>
        <xsl:text>=LDR  00000nam  2200000Ia 4500</xsl:text>
        <xsl:text>&#13;&#10;</xsl:text>
        <xsl:apply-templates select="descendant::td[text() = 'Book Location ']" />
      </xsl:template>
    
      <xsl:template match="td">
       <xsl:text>=952  \\$cLocation: </xsl:text>
       <xsl:value-of select="following-sibling::*[1]" />
      </xsl:template> 
    
    </xsl:stylesheet>
    

    Note: