Subject: Re: [xsl] Newbie - simple selection problem From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx> Date: Fri, 30 Nov 2001 17:54:39 +0000 |
Hi Jim, There are two things in XPath that look very similar to each other: paths that select nodes and patterns that match nodes. You're confusing the two. The match attribute of xsl:template holds a pattern that matches nodes. If you apply templates to a node then the template will be used on the node if the node matches the pattern. For example: > <xsl:template match="AAA/BBB/CCC[data_status = 'OK']"> This *matches* CCC elements whose parent is a BBB element and whose grandparent is an AAA element, and that has a data_status child element with a value of 'OK'. If you apply templates to a CCC element that meets that description, then this is the template that will be used to generate the result from it. Within the template, the current node, the node you're processing, is a CCC element. The select attribute of xsl:apply-templates and xsl:for-each holds a path that selects nodes. The path is resolved relative to the current node - the node that you're currently processing. So if within a template that matches a CCC element you do: > <xsl:for-each select ="AAA"> then you create some output for each AAA element that's a child of the CCC element. If there aren't any, you don't create any output. Usually you should select the nodes that you want to process within the select attribute of an xsl:apply-templates to apply templates to them. So if you want to process AAA elements whose child BBB element's child CCC element's data_status child element has a value of 'OK', and you're currently on the DocRoot element parent of the AAA element, you need to do: <xsl:apply-templates select="AAA[BBB/CCC/data_status = 'OK']" /> You are applying templates to AAA elements so you need a template that matches AAA elements. A template that matches AAA elements will look like: <xsl:template match="AAA"> ... </xsl:template> If you're familiar with CSS, you might find it helpful to think of templates as rules like CSS rules. The match pattern holds the selector for the rule, and the content of the template is what gets done with elements of that type. It's just that in XSLT you can choose which elements get templates applied to them whereas in CSS then everything has rules applied to them. So to create a table of information holding rows generated from AAA elements whose child BBB element's child CCC element's data_status child has a value of 'OK' you need to have a template that only gets applied once to generate the table element. The template for the DocRoot element is a good place for this: <xsl:template match="DocRoot"> <TABLE> <TR> <TD> <B>Table start stuff</B> </TD> </TR> <xsl:apply-templates select="AAA[BBB/CCC/data_status = 'OK']" /> </TABLE> </xsl:template> Then you can have a template that matches AAA elements and generates the rows of the table: <xsl:template match="AAA"> <TR> <TD><xsl:value-of select="BBB/detailed_bbb1"/></TD> <TD><xsl:value-of select="BBB/detailed_bbb2"/></TD> <TD><xsl:value-of select="DDD/detailed_ddd1"/></TD> </TR> </xsl:template> If you prefer, you can use xsl:for-each to iterate over the AAA elements rather than applying templates to them, as follows: <xsl:template match="DocRoot"> <TABLE> <TR> <TD> <B>Table start stuff</B> </TD> </TR> <xsl:for-each select="AAA[BBB/CCC/data_status = 'OK']"> <TR> <TD><xsl:value-of select="BBB/detailed_bbb1"/></TD> <TD><xsl:value-of select="BBB/detailed_bbb2"/></TD> <TD><xsl:value-of select="DDD/detailed_ddd1"/></TD> </TR> </xsl:for-each> </TABLE> </xsl:template> I hope that helps, Jeni --- Jeni Tennison http://www.jenitennison.com/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] Newbie - simple selection pro, JWALLIS | Thread | [xsl] Selection based on date compa, Dennis Campillo |
Re: [xsl] xsltTool for mxl-xml Tran, Sanjay Manchanda | Date | RE: [xsl] Mysterious 'invalid chara, Hunsberger, Peter |
Month |