RE: [xsl] Displaying multiple instances of the same tag

Subject: RE: [xsl] Displaying multiple instances of the same tag
From: "M. David Peterson" <m.david@xxxxxxxxxx>
Date: Sun, 13 Jun 2004 14:33:49 -0600
Daniel,

Let me give you two solutions to your problem.  The first one take's
your existing code and adds a couple lines to give you what you want (if
I interpreted the "top of you table" correctly.)

The second takes your XML and transforms it using logical recursion.
The benefits to the second method are pretty straightforward...

1) Code management: Making changes to the background color of a
particular row can be done in more logical format, exposing each
individual element as it's own object who's properties can be changed
from embedded XML or a separate XML file (I used embedded XML to make it
easier but you can reference an external XML file with the document
function as well).  In fact there are several ways of developing
stylesheets that will allow you to literally make adjustment to things
like width, height, length, color, etc...  In fact any property that is
available in HTML or CSS could be accessed through a simple XML
interface allowing the ability to never have to touch your stylsheet
again if you don't want.  I'll leave it to your imagination to take it
form here.

2) The second and probably most important reason is performance.  If you
do two things: Adjust your XML in a way that doesn't require to go
backwards to access properties that were found earlier in the tree AND
then process these elements starting with the children of the root
element and then using recursion to process each descendant.  

The stylesheet to perform what I am referring is just below this first
stylesheet.  I took some liberty to make some minor modifications to the
layout for no other reason than to break each part of the XML out a bit
more to see what's taking place during the transformation.  Please don't
take that as criticism to your design but simply a way to make the code
difference more obvious.

The reason I am taking the time to show you this is pretty simple.  I
myself have had the experience of the "light" turning on when you
realize just what XSLT is capable of...  the "WHOA! That's how that
works... That makes soooooooo much sense and is soooooo powerful" is a
moment you will never forget.  I have also seen how the "light" being
turned on has effected other people and there development in a very
positive manner and I get a kick out of seeing that happen.  So, with
that said....

Solution 1: 

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited with XML Spy v4.2 -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
<xsl:template match="/">
<html>
<body>
  
   <h2>Your Selection</h2>
   <h3>Quotes</h3>
   <ul>
     <xsl:apply-templates select="catalog/cd/quote"/>
   </ul>
   <table border="1">
     <tr bgcolor="#9acd32">
       <th>Title</th>
       <th>Artist</th>
     </tr>
     <xsl:for-each select="catalog/cd">
     <tr>
       <td><xsl:value-of select="title"/>
	  </td>
       <xsl:choose>
       <xsl:when test="artist = 'Book'">
          <td bgcolor="#ff00ff">
          <xsl:value-of select="name"/>
          </td>
       </xsl:when>
       <xsl:when test="artist = 'Journal Article'">
          <td bgcolor="#cccccc">
          <xsl:value-of select="journal"/></td>
       </xsl:when>
       <xsl:otherwise>
          <td><xsl:value-of select="artist"/></td>
		
       </xsl:otherwise>
       </xsl:choose>
	  </tr>
     </xsl:for-each>
   </table>
</body>
</html>
</xsl:template>
<xsl:template match="quote">
  <li><xsl:value-of select=". "/></li>
</xsl:template>
</xsl:stylesheet>

And then solution 2 (I added quote elements (copy & paste so there the
same) to all three cd entries in the source, again just to showcase the
process):

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
xmlns:properties="uri:properties:elements[element]"
extension-element-prefixes="properties">

<properties:elements>
  <element artist="Book" select="name">#ff00ff</element>
  <element artist="Journal Article" select="journal">#cccccc</element >
  <element artist="Dan Palmer" select="artist">#ffffff</element >
</properties:elements>

<xsl:variable name="elements"
select="document('')/*/properties:elements/element"/>

<xsl:template match="/">
  <html>
    <body>
      <xsl:apply-templates select="catalog"/>
    </body>
  </html>
</xsl:template>

<xsl:template match="catalog">
    <h2>Your Selections</h2>
     <xsl:apply-templates select="cd"/>    
</xsl:template>

<xsl:template match="cd">
<xsl:variable name="artist" select="artist"/> 
<table border="1">
    <tr>
        <th>Title</th>
        <th>Artist</th>
    </tr>
  <tr>
      <td bgcolor="{$elements[@artist = $artist]}"><xsl:value-of
select="title"/></td>
      <td ><xsl:value-of select="child::*[local-name() =
$elements[@artist = $artist]/@select]"/></td>
  </tr>
</table>
 <h2>Quote from this artist:</h2>
<ul>
  <xsl:apply-templates select="quote"/>
</ul>
</xsl:template>

<xsl:template match="quote">
      <li><xsl:value-of select="."/></li>
</xsl:template>

</xsl:stylesheet>

This code base gives you this output: (using the modified XML):

<html>
   <body>
      <h2>Your Selections</h2>
      <table border="1">
         <tr>
            <th>Title</th>
            <th>Artist</th>
         </tr>
         <tr>
            <td bgcolor="#ff00ff">Empire Burlesque</td>
            <td>Transaction Yeah</td>
         </tr>
      </table>
      <h2>Quote from this artist:</h2>
      <ul>
         <li>I am cool</li>
         <li>You are cool</li>
         <li>We are cool</li>
      </ul>
      <table border="1">
         <tr>
            <th>Title</th>
            <th>Artist</th>
         </tr>
         <tr>
            <td bgcolor="#cccccc">Hide your heart</td>
            <td>Transactions</td>
         </tr>
      </table>
      <h2>Quote from this artist:</h2>
      <ul>
         <li>I am cool</li>
         <li>You are cool</li>
         <li>We are cool</li>
      </ul>
      <table border="1">
         <tr>
            <th>Title</th>
            <th>Artist</th>
         </tr>
         <tr>
            <td bgcolor="#ffffff">Greatest Hits</td>
            <td>Dan Palmer</td>
         </tr>
      </table>
      <h2>Quote from this artist:</h2>
      <ul>
         <li>I am cool</li>
         <li>You are cool</li>
         <li>We are cool</li>
      </ul>
   </body>
</html>

Best of luck to you!

<M:D/>


-----Original Message-----
From: Daniel Palmer [mailto:Daniel.Palmer@xxxxxxxxxxxxxxxxxxxxxxx] 
Sent: Sunday, June 13, 2004 11:55 AM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: Re: [xsl] Displaying multiple instances of the same tag

Thanks to Sameer and Josh for their suggestions,

Actually, I tried every way I could think of of adding:

<xsl:appy-templates select="quote"/>
and
<xsl:template match="quote">
   <xsl:value-of select="." />
</xsl:template>

to my xsl stylesheet unsuccessfully.  If anyone is able to show me what 
the xsl file should look like with a display all quotes template above 
the table, I'd be very grateful (and promise to bother you no more!).

here is my xsl:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited with XML Spy v4.2 -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
<xsl:template match="/">
<html>
<body>

   <h2>Your Selection</h2>
   <table border="1">
     <tr bgcolor="#9acd32">
       <th>Title</th>
       <th>Artist</th>
     </tr>
     <xsl:for-each select="catalog/cd">
     <tr>
       <td><xsl:value-of select="title"/>
	  </td>
       <xsl:choose>
       <xsl:when test="artist = 'Book'">
          <td bgcolor="#ff00ff">
          <xsl:value-of select="name"/>
          </td>
       </xsl:when>
       <xsl:when test="artist = 'Journal Article'">
          <td bgcolor="#cccccc">
          <xsl:value-of select="journal"/></td>
       </xsl:when>
       <xsl:otherwise>
          <td><xsl:value-of select="artist"/></td>
		
       </xsl:otherwise>
       </xsl:choose>
	  </tr>
     </xsl:for-each>
   </table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

and here is my xml:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited with XML Spy v4.2 -->
<?xml-stylesheet type="text/xsl" href="cdcatalog_choose2.xsl"?>
<catalog>
	<cd>
		<title>Empire Burlesque</title>
		<artist>Book</artist>
		<name>Transaction Yeah</name>
		<country>USA</country>
		<company>Columbia</company>
		<price>10.90</price>
		<year>1985</year>
		<quote>I am cool</quote>
		<quote>You are cool</quote>
		<quote>We are cool</quote>
	</cd>
	<cd>
		<title>Hide your heart</title>
		<artist>Journal Article</artist>
		<journal>Transactions</journal>
		<country>UK</country>
		<company>CBS Records</company>
		<price>9.90</price>
		<year>1988</year>
	</cd>
	<cd>
		<title>Greatest Hits</title>
		<artist>Dan Palmer</artist>
		<country>USA</country>
		<company>RCA</company>
		<price>9.90</price>
		<year>1982</year>
	</cd>
</catalog>

Best,
Dan


On 12/06/2004, at 3:45 PM, Samooo wrote:

> You can use
> <xsl:appy-templates select="quote"/>
> and
> <xsl:template match="quote">
>   <xsl:value-of select="." />
> </xsl:template>
>
>
> Sameer.
>
> ----- Original Message -----
> From: "Daniel Palmer" <Daniel.Palmer@xxxxxxxxxxxxxxxxxxxxxxx>
> To: <xsl-list@xxxxxxxxxxxxxxxxxxxxxx>
> Sent: Saturday, June 12, 2004 9:44 AM
> Subject: [xsl] Displaying multiple instances of the same tag
>
>
>> The xml I've been playing with looks like this:
>>
>> <reference>
>> <title>Empire</title>
>> <artist>Book</artist>
>> <country>USA</country>
>> <company>Columbia</company>
>> <price>10.90</price>
>> <year>1985</year>
>> <quote>I am cool</quote>
>> <quote>You are cool</quote>
>> <quote>We are cool</quote>
>> </reference>
>>
>> In xsl,  <xsl:value-of select="quote"/> of course displays only the
>> first quote.  Can someone tell me how to specify in xsl which and how
>> many of the quotes to display in xml?  I searched the archives and
the
>> other recommended FAQ page unsuccessfully.
>>
>> Best,
>> Dan Palmer
>>
>>
>> --+------------------------------------------------------------------
>> XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
>> To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
>> or e-mail: <mailto:xsl-list-unsubscribe@xxxxxxxxxxxxxxxxxxxxxx>
>> --+--
>>
>>
>
> --+------------------------------------------------------------------
> XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
> To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
> or e-mail: <mailto:xsl-list-unsubscribe@xxxxxxxxxxxxxxxxxxxxxx>
> --+--
>


--+------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe@xxxxxxxxxxxxxxxxxxxxxx>
--+--


Current Thread