0

This question is related with this question xslt xpath using element values in xpath query however, the xslt is only for two element nodes HAS TAXONOMIC LEVEL and IS USED AS.

Please find the following xmls:

<root>
 <html>
  <table class=" table search-results-property-table">  
                 ....
   <tr>
    <td>
     <span class="versal">HAS TAXONOMIC LEVEL</span>
    </td>
    <td>
     <ul>
      <li>
       <a class="versal" href="../../../agrovoc/en/page/c_11125">genus</a>
      </li>
     </ul>
    </td>
   </tr>
   <tr>
    <td>
     <span class="versal">IS USED AS</span>
    </td>
    <td>
     <ul>
      <li>
       <a class="versal" href="../../../agrovoc/en/page/c_1591">christmas trees</a>
      </li>
      <li>
       <a class="versal" href="../../../agrovoc/en/page/c_7776">timber trees</a>
      </li>
     </ul>
    </td>
   </tr>
    ....
  <table>
 </html>
 <html>
     .....      
   <tr>
    <td>
     <span class="versal">ANOTHER HEADING LABEL</span>
    </td>
    <td>
     <ul>
      <li>
       <p>values</p>
      </li>
     </ul>
    </td>
   </tr>
       ....
 </html>
 <html>
   [third data set...]
    ...
 </html>    
<root>

I want to have the element values HAS TAXONOMIC LEVEL, IS USED AS and other LABELS in /tr/td/span[@class='versal] be used in xpath. Next is to output their values (e.g. HAS TAXONOMIC LEVEL) and then get the values of the descendant "a" or "p" of sibling "td" /ul/li/a -> genus under HAS TAXONOMIC LEVEL and christmas trees and timber trees under IS USED AS. And lastly, get the @href if it's available. So I get the following:

START HERE
=LDR  00000nam  2200000Ia 4500
     ....
=305  \\$aHAS TAXONOMIC LEVEL$bgenus$cc_11125
=305  \\$aIS USED AS$bchrismas trees$cc_1591
=305  \\$aIS USED AS$btimber trees$cc_7776

START HERE
=LDR  00000nam  2200000Ia 4500
      ....
=305  \\$aLABEL$bvalue

START HERE
=LDR  00000nam  2200000Ia 4500
  (third data set and so on..)

Please take note that I have more than one document in this file with xml format like below:

<root>
 <html>
   [DATA SET 1]
         ....
 </html>
      <html>
   [DATA SET 2]
         ....
 </html>
       .....
</root>

I have the following existing xslt to fit it in:

<?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" omit-xml-declaration="yes" indent="no"/>

 <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:apply-templates select="table/prefterm" />
  <xsl:text>&#13;&#10;</xsl:text>   
  <xsl:apply-templates select="table/tr/td/span" />
  <xsl:text>&#13;&#10;</xsl:text>   
       ....
 </xsl:stylesheet>

Thanks and cheers!

UPDATE2: With the following xslt below:

<?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" omit-xml-declaration="yes" indent="no"/>

 <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:apply-templates select="table/prefterm" />
  <xsl:text>&#13;&#10;</xsl:text>   
  <xsl:apply-templates select="table/tr/td/span" />
  <xsl:text>&#13;&#10;</xsl:text>   
  <xsl:apply-templates select="table/tr"/>
  <xsl:text>&#13;&#10;</xsl:text>
       .......
 <xsl:template match="table/tr">
  <xsl:for-each select="../tr[td/span/@class='versal']">
   <xsl:variable name="span" select="td/span" />
   <xsl:for-each select="td/ul/li/a">
   <xsl:text>=305  \\$a</xsl:text>
   <xsl:value-of select="$span"/>
   <xsl:text>$c</xsl:text>
   <xsl:value-of select="."/>
   <xsl:text>&#10;</xsl:text>
   </xsl:for-each>
  </xsl:for-each> 
 </xsl:template>

</xsl:stylesheet>

With this template I'm getting many values repeated several times that is seem is based on the number of another node like below:

START HERE
=LDR  00000nam  2200000Ia 4500    
 .....
=305  \\$aHAS TAXONOMIC LEVEL$cgenus
=305  \\$aIS USED AS$cchristmas trees
=305  \\$aIS USED AS$ctimber trees
=305  \\$aHAS TAXONOMIC LEVEL$cgenus
=305  \\$aIS USED AS$cchristmas trees
=305  \\$aIS USED AS$ctimber trees

START HERE
=LDR  00000nam  2200000Ia 4500    
 ..... set 2 and also =305 is printed many times

1 Answer 1

0

In the previous question, the expression give is this....

<xsl:for-each select="html/table/tr[td/span='HAS TAXONOMIC LEVEL' or td/span='IS USED AS']">

If you want to include other values, change it to this...

 <xsl:for-each select="html/table/tr[td/span/@class='versal']">

Looking at your output though, it looks like you want a new section for each html element, so might put the code in a template that matches html. Something like this...

<xsl:template match="html">
    <xsl:text>START HERE</xsl:text>
    <xsl:for-each select="table/tr[td/span/@class='versal']">
        <!-- Existing code -->
    </xsl:for-each> 
</xsl:template>

EDIT: To fit it into your (second) XSLT, try this instead

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text" omit-xml-declaration="yes" indent="no"/>

 <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:for-each select="table/tr[td/span/@class='versal']">
       <xsl:variable name="span" select="td/span" />
       <xsl:for-each select="td/ul/li/a">
         <xsl:text>=305  \\$a</xsl:text>
         <xsl:value-of select="$span"/>
         <xsl:text>$c</xsl:text>
         <xsl:value-of select="."/>
         <xsl:text>&#10;</xsl:text>
       </xsl:for-each>
     </xsl:for-each> 
   </xsl:for-each> 
 </xsl:template>
</xsl:stylesheet>

The main problem in your existing XSLT is that you do <xsl:for-each select="//table/tr[td/span/@class='versal']">, but the //table will get all tables in the document, so you lose context. You need to do just <xsl:for-each select="table/tr[td/span/@class='versal']">

Sign up to request clarification or add additional context in comments.

3 Comments

Hi! I actually have this existing xslts: <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:apply-templates select="table/prefterm" /> <xsl:text>&#13;&#10;</xsl:text> <xsl:apply-templates select="table/tr/td/span" /> <xsl:text>&#13;&#10;</xsl:text> <xsl:apply-templates select="table/tr"/> <xsl:text>&#13;&#10;</xsl:text> I'll try to fit it in.
@schnydszch I've included a full XSLT sample in my answer, if it helps.
Thanks Tim C. you're answer fits really well resolving my problem, and also I learned that I can have xsl:for-each inside xsl:for-each in my first template (template match="root"). That's why I was losing context.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.