Subject: Re: template matches more than once From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx> Date: Thu, 03 Aug 2000 20:42:34 +0100 |
Tom, This problem stems from applying templates to a larger set of nodes than those you actually want to process. In your root-matching template: <xsl:template match="/"> <HTML> <HEAD></HEAD> <BODY> <p>Select clause = //item - i.e. select all item' elements in tree regardless of ancestry.</p> <xsl:apply-templates select="//item" /> </BODY> </HTML> </xsl:template> you apply templates to *all* the item descendents of the root node (i.e. all the item elements in the document). You have a template that deals with those items for which the @item_ParentID is '2': <xsl:template match="item[@item_ParentID='2']"> <p> <xsl:value-of select="@item_text" /> </p> </xsl:template> But all the other item elements are processed by the built-in template: <xsl:template match="*|/"> <xsl:apply-templates/> </xsl:template> Your item elements are nested inside each other, so when your 'File' item is processed by the built-in template, templates are applied to all its children: the 'Save' and 'Documents' items. So, the 'Save' and 'Documents' items are processed twice, once because they are selected as descendent items of the root node, and once because they are processed as children of the 'File' item. There are three ways to solve this problem. The first is to stop the built-in rule applying to the item elements that you don't want to match by adding an item-matching template that does nothing: <xsl:template match="item" /> The second is to take advantage of the built-in templates and change your root-mode-matching template to process the first level of items, letting the built-in templates process the children of these items until you get to the items that you actually want to give some output for: <xsl:template match="/"> <HTML> <HEAD></HEAD> <BODY> <p>Select clause = //item - i.e. select all item' elements in tree regardless of ancestry.</p> <xsl:apply-templates select="/menu/item" /> </BODY> </HTML> </xsl:template> The third is to only process those items that you're actually interested in in the first place and have a general item-matching template to give their content: <xsl:template match="/"> <HTML> <HEAD></HEAD> <BODY> <p>Select clause = //item - i.e. select all item' elements in tree regardless of ancestry.</p> <xsl:apply-templates select="//item[@item_ParentID='2']" /> </BODY> </HTML> </xsl:template> <xsl:template match="item"> <p> <xsl:value-of select="@item_text" /> </p> </xsl:template> This latter is probably the most efficient because every time you apply templates on a node it takes time to find the templates to be applied to it: the fewer nodes you select to process, the less time it takes. I hope this helps, Jeni Dr Jeni Tennison Epistemics Ltd * Strelley Hall * Nottingham * NG8 6PE tel: 0115 906 1301 * fax: 0115 906 1304 * email: jeni.tennison@xxxxxxxxxxxxxxxx XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
template matches more than once, Tom Power | Thread | Re: template matches more than once, Rudolf P. Weinmann |
Re: XSL Sort and Xalan, Bryce Wells | Date | Re: running msxml3 from command lin, Jon Smirl |
Month |