[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: for-each question

Subject: Re: for-each question
From: Mike Brown <mike@xxxxxxxx>
Date: Mon, 12 Aug 2002 20:02:28 -0600 (MDT)
Re:  for-each question
Holmberg Rick-ra0119 wrote:
> I am new to Xsl and am trying to parse a xml document into a html doc.  I would like to have a heading above several elements but don't want that heading to show up above each element.  I am sure this is simple but I can't seem to quite get it.  Here is what I have.
>  
> If my xml file looks like this
> <?xml version="1.0" encoding="UTF-8"?>
> <test>
> <id>TestId</id>
> <book>ABC123</book>
> <book>ABC456</book>
> <book>ABC789</book>
> </test>
>  
> I would like the html to read
> The Books are:
> ABC123
> ABC456
> ABC789
>  
> My Stylesheet segment is:
>  
> <xsl:stylesheet version="1.0"
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
> <xsl:output omit-xml-declaration="yes"/>             
> <xsl:output method="html"/>
>  
> <xsl:template match="/">
>     <xsl:copy>
>       <xsl:apply-templates/>
>     </xsl:copy>
> </xsl:template>
>  
> <xsl:template match="book">
> <I>
> The Books are:
> <xsl:apply-templates select="book" />
> <xsl:apply-templates/>
> </I>
> </xsl:template>
>  
>  
> With this XSL file I am getting the 'The Books are:' printed 3 times.  

That's right. The template that matches a 'book' element is being invoked 3 
times. A built-in template that matches any element is matching on your 'test'
element and proceding on to all its children, which include the 'id' 
element, the three 'book's, and some whitespace-only text nodes in between.

You would do well to read about the processing model used by XSLT, including
the XPath/XSLT data model and how templates are invoked.

Your stylesheet should contain just these templates:

<xsl:template match="test">
  <I>The books are:</I>
  <xsl:apply-templates select="book"/>
</xsl:template>

<xsl:template match="book">
  <xsl:value-of select="."/>
  <xsl:if test="position() &lt; last()">, </xsl:if>
</xsl:template>

What this means is, when processing a 'test' element (which the built-in
templates will lead you to), you want to add an 'I' element to the result
tree, containing 'The books are:', and following that will be the result
of instantiating the best matching templates for each of the 'book' children 
of the 'test' element. And when processing a 'book' element, you want the 
string-value (XPath terminology for the text content) of that element, 
followed by ', ' if the current node is not the last of the nodes that
were selected for processing (in this case, the current 'book' is not the 
last of all the 'book's).

   - Mike
____________________________________________________________________________
  mike j. brown                   |  xml/xslt: http://skew.org/xml/
  denver/boulder, colorado, usa   |  resume: http://skew.org/~mike/resume/

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.