This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: for-each question
- From: Mike Brown <mike at skew dot org>
- To: xsl-list at lists dot mulberrytech dot com
- Date: Mon, 12 Aug 2002 20:02:28 -0600 (MDT)
- Subject: Re: [xsl] for-each question
- Reply-to: xsl-list at lists dot mulberrytech dot com
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() < 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