Hi Dennis, > Since the template doesn't know in which level of the hierarchy it > is, it can't indent the output correctly. > > How would you do this? Is there a way to recursively traverse the > nodes? So when I'm at a group node, it would call a template to > check again for group and field and branch off from there > recursively? XSLT is designed to work in this kind of recursive way. In your case, as you describe, you would have two templates: one matching group elements and one matching field elements, and the different templates would do different things. This is a very neat way of doing it if you're producing HTML and using CSS to produce the indentation that you want. You can use div elements in HTML to add indentation at each level (or if you want a quick-and-dirty way, use blockquote elements): <xsl:template match="group"> <div class="indent"> GROUP-LEVEL <xsl:apply-templates /> </div> </xsl:template> <xsl:template match="field"> FIELD-LEVEL </xsl:template> If you're producing text, on the other hand, then the easiest way to achieve the indentation is to pass down a 'indent' parameter from template to template. You can make a template accept a parameter with a xsl:param element. When you apply templates to the child elements of the group element, you need to pass on the parameter with the xsl:with-param element. At each group element, add some more to the indent that you pass down by concatenating some more spaces to the indent: <xsl:template match="group"> <xsl:param name="indent" /> <xsl:value-of select="$indent" /> <xsl:text>GROUP-LEVEL
<xsl:text> <xsl:apply-templates> <xsl:with-param name="indent" select="concat($indent, ' ')" /> </xsl:apply-templates> </xsl:template> <xsl:template match="field"> <xsl:param name="indent" /> <xsl:value-of select="$indent" /> <xsl:text>FIELD-LEVEL
</xsl:text> </xsl:template> If you don't like this approach, you could continue to apply templates to all the descendants and then work out the depth of the element by counting how many ancestors it has with: count(ancestor::*) and use that as the basis for an indentation or whatever. However, this is a lot more fiddly and it's likely to be a lot more inefficient than working going with the XSLT flow as described above. I hope that helps, Jeni --- Jeni Tennison http://www.jenitennison.com/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
PURCHASE STYLUS STUDIO ONLINE TODAY!
Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!
Download The World's Best XML IDE!
Accelerate XML development with our award-winning XML IDE - Download a free trial today!
Subscribe in XML format