Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

New Member - XML problems 1

Status
Not open for further replies.

SandyUK

Programmer
Feb 3, 2006
2
0
0
GB
Hi all,

having problems with my XML/XSL files.

I have an XML file that contains detaiols of my MP3 collection, it is structured into MP3 Collection/ artist/album/trackname.

I have XSL file that is displaying the date how I want, (Apart from the tracknames, only showing the first)

Wondering if anyone can see what is wrong with the following files:

mp3.xsl:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="
<xsl:template match="/">
<html>
<body>
<h2>MP3 Collection</h2>
<table border="1">
<xsl:for-each select="mp3list/artist">
<tr>
<td>
<xsl:value-of select="artistname"/>
<table border="1" style="margin-left:20px">
<xsl:for-each select="album">
<tr>
<td>
<xsl:value-of select="albumname"/>

<table border="1" style="margin-left:20px">
<xsl:for-each select="track">
<tr>
<td>
<xsl:value-of select="trackname"/>
</td>
</tr>
</xsl:for-each>
</table>

</td>
</tr>
</xsl:for-each>
</table>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>

</xsl:stylesheet>

mp3.xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="mp3.xsl"?>

<mp3list>
<artist>
<artist>
<artistname>10000 Maniacs</artistname>
<album>
<albumname>In my Tribe</albumname>
<track>
<trackname>01</trackname>
<trackname>02</trackname>
<trackname>03</trackname>
<trackname>04</trackname>
<trackname>05</trackname>
<trackname>06</trackname>
<trackname>07</trackname>
<trackname>08</trackname>
<trackname>09</trackname>
<trackname>10</trackname>
</track>
</album>
</artist>
<artist>
<artistname>AC-DC</artistname>
<album>
<albumname>Back In Black</albumname>
<track>
<trackname>01</trackname>
<trackname>02</trackname>
<trackname>03</trackname>
<trackname>04</trackname>
<trackname>05</trackname>
<trackname>06</trackname>
<trackname>07</trackname>
<trackname>08</trackname>
<trackname>09</trackname>
<trackname>10</trackname>
</track>
</album>
<album>
<albumname>For Those About To Rock</albumname>
<track>
<trackname>01</trackname>
<trackname>02</trackname>
<trackname>03</trackname>
<trackname>04</trackname>
<trackname>05</trackname>
<trackname>06</trackname>
<trackname>07</trackname>
<trackname>08</trackname>
<trackname>09</trackname>
<trackname>10</trackname>
</track>
</album>
</artist>
</mp3list>

Any and all help would be most aprreciated.

Thanks in advance,

Sandy
 
You need to do a for-each on trackname rather than track.

<xsl:for-each select="track/trackname">
<tr>
<td>
<xsl:value-of select="."/>
</td>
</tr>
</xsl:for-each>
 
Theaks for that, I've been stumped for over a day.

Can you explain why it has to be that way, when all the others use the same syntax?

Sandy
 
The xsl:for-each (or apply-templates) essentially contains a template which is initiated for each node selected in the expression. So if if you do this:

<xsl:for-each select="track">
<tr>
<td>
<xsl:value-of select="trackname"/>
</td>
</tr>
</xsl:for-each>

the template is processed just once for each track and trackname would take the first trackname in the tree.

The following would display tracks 1,2 and 5 in the tree.

<xsl:for-each select="track">
<tr>
<td>
<xsl:value-of select="trackname[1]"/>
<xsl:value-of select="trackname[2]"/>
<xsl:value-of select="trackname[5]"/>
</td>
</tr>
</xsl:for-each>




 
I would avoid the use of for-each where it is semantically better to use apply-templates. It is much clearer, modular and more easily extensible. I would only use for-each when the nodelist breaks from the structure of the original XML.
Code:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="[URL unfurl="true"]http://www.w3.org/1999/XSL/Transform">[/URL]
  <xsl:template match="/">
    <xsl:apply-templates select="mp3list"/>
  </xsl:template>
  <xsl:template match="mp3list">
    <html>
      <body>
        <h2>MP3 Collection</h2>
        <table border="1">
          <xsl:apply-templates select="artist"/>
        </table>
      </body>
    </html>
  </xsl:template>
  <xsl:template match="artist">
    <tr>
      <td>
        <xsl:value-of select="artistname"/>
        <table border="1" style="margin-left:20px">
          <xsl:apply-templates select="album"/>
        </table>
      </td>
    </tr>
  </xsl:template>
  <xsl:template match="album">
    <tr>
      <td>
        <xsl:value-of select="albumname"/>
        <table border="1" style="margin-left:20px">
          <xsl:apply-templates select="track"/>
        </table>
      </td>
    </tr>
  </xsl:template>
  <xsl:template match="track">
    <tr>
      <xsl:apply-templates select="trackname"/>
    </tr>
  </xsl:template>
  <xsl:template match="trackname">
    <td>
      <xsl:value-of select="."/>
    </td>
  </xsl:template>
</xsl:stylesheet>
As far as the XML is concerned, I would look at making than more semantic too:
Code:
<mp3list>
  <artist>
    <name>10000 Maniacs</name>
    <albums>
      <album>
        <name>In my Tribe</name>
        <tracks>
          <track>
            <name>01</name>
          </track>
          <track>
            <name>02</name>
          </track>
          <track>
            <name>03</name>
          </track>
        </tracks>
      </album>
    </albums>
  </artist>
</mp3list>
Finally, the HTML should also be more semantic. Tables are for tabular data. This data is a more like a list. Personally, I would use ordered lists for the tracks nested in definition lists for artists/albums, then use CSS to style it.

Jon

"I don't regret this, but I both rue and lament it.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top