0
votes

I have a xml and xsl as shown below I want to display all the values in the xml

Input XML

    <?xml version="1.0" encoding="UTF-8"?>
    <catalog>
        <cd>
          <test>
            <title>Empire Burlesque</title>
            <artist>Bob Dylan</artist>
          </test>
          <test1>
            <country>USA</country>
            <company>Columbia</company>
            <price>10.90</price>
            <year>1985</year>
          </test1>
        </cd>
        <cd>
            <test>
            <title>Hide your heart</title>
            <artist>Bonnie Tyler</artist>
            </test>
            <test1>
            <country>UK</country>
            <company>CBS Records</company>
            <price>9.90</price>
            <year>1988</year>
            </test1>
        </cd>
    </catalog>

XSLT

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
  <html>
  <body>
  <h2>My CD Collection</h2>
    <table border="1">
      <tr bgcolor="#9acd32">
        <th style="text-align:left">Title</th>
        <th style="text-align:left">Artist</th>
         <!--<th style="text-align:left">country</th>
        <th style="text-align:left">company</th>-->
      </tr>
      <xsl:for-each select="catalog/cd/test">
      <tr>
        <td><xsl:value-of select="//title"/></td>
        <td><xsl:value-of select="//artist"/></td>
        <!--<td><xsl:value-of select="//country"/></td>
        <td><xsl:value-of select="//company"/></td>-->
      </tr>
      </xsl:for-each>
    </table>
  </body>
  </html>
</xsl:template>
</xsl:stylesheet>

I want to display the title, artist, country and company values of all the cd loop. By the above code I can only display the first value. Can any help me how to loop through the xml and display all the values.

3

3 Answers

0
votes

It is better to "loop" on the cd that way:

<xsl:template match="/">
  <html>
  <body>
  <h2>My CD Collection</h2>
    <table border="1">
      <tr bgcolor="#9acd32">
        <th style="text-align:left">Title</th>
        <th style="text-align:left">Artist</th>
         <th style="text-align:left">country</th>
        <th style="text-align:left">company</th>
      </tr>
      <xsl:for-each select="catalog/cd">
      <tr>
        <td><xsl:value-of select="test/title"/></td>
        <td><xsl:value-of select="test/artist"/></td>
        <td><xsl:value-of select="test1/country"/></td>
        <td><xsl:value-of select="test1/company"/></td>
      </tr>
      </xsl:for-each>
    </table>
  </body>
  </html>
</xsl:template>

This is the result :

<html>
   <body>
      <h2>My CD Collection</h2>
      <table border="1">
         <tr bgcolor="#9acd32">
            <th style="text-align:left">Title</th>
            <th style="text-align:left">Artist</th>
            <th style="text-align:left">country</th>
            <th style="text-align:left">company</th>
         </tr>
         <tr>
            <td>Empire Burlesque</td>
            <td>Bob Dylan</td>
            <td>USA</td>
            <td>Columbia</td>
         </tr>
         <tr>
            <td>Hide your heart</td>
            <td>Bonnie Tyler</td>
            <td>UK</td>
            <td>CBS Records</td>
         </tr>
      </table>
   </body>
</html>
0
votes

The problem is with your use of xsl:value-of

<td><xsl:value-of select="//title"/></td>
<td><xsl:value-of select="//artist"/></td>

When you start an expression with a forward slash /, then this represents the document node, so the expression will be relative to that, not the node you are currently positioned on. Using // then means it will search for nodes at any level in your XML document, regardless of the node you are on.

Just change your expressions to this instead, so they are relative to the test node you are positioned on

<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="artist"/></td>
0
votes

First the xml sample you have put in the question, need to ne fixed . Because test1 tag on the 1st cd node has no end tag.

Child tag names inside "cd" tag are not test all the time. It varies. Its not "test" all the time. So the looping control you have used need to modified to loop on /catalog/cd as below and the select statement inside loop should be for any child as below.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
<html>
  <body>
  <h2>My CD Collection</h2>
  <table border="1">
    <tr bgcolor="#9acd32">
    <th style="text-align:left">Title</th>
    <th style="text-align:left">Artist</th>
     <!--<th style="text-align:left">country</th>
    <th style="text-align:left">company</th>-->
  </tr>
  <xsl:for-each select="catalog/cd">
  <tr>
    <td><xsl:value-of select="child::*/title"/></td>
    <td><xsl:value-of select="child::*/artist"/></td>
    <!--<td><xsl:value-of select="//country"/></td>
    <td><xsl:value-of select="//company"/></td>-->
  </tr>
  </xsl:for-each>
</table>
</body>
</html>
</xsl:template>