[XSL-LIST Mailing List Archive Home]
[By Thread]
[By Date]
Re: [xsl] Conditional counting
Subject: Re: [xsl] Conditional counting From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx> Date: Fri, 12 Oct 2001 09:29:30 +0100 |
Hi Peter, > I've got an XSLt running under LotusXSLt (Xalan) that conditionally calls > two different extensions: > > <table border="1"> > <xsl:if test="$gunk = 'x''"> > <xsl:apply-templates select="myExt.method1(*)" mode="x" /> > </xsl:if> > <xsl:if test="$gunk != 'x'"> > <xsl:apply-templates select="myExt.method2(*)" mode="x"/> > </xsl:if> > </table> > <xsl:value-of select="count(tr)"/> rows generated. > > The returned results will include a varying number of <tr> tags > (table rows) independent of the passed XML I'd like to have the > count reflect the number of tr tags returned from the extensions. As > it is, the count is going to reflect the number of <tr> tags in the > input XML (zero in our case). [snip] > I've tried a couple of differing approaches, in particular with placing the > extension results into a variable and then parsing the variable and counting > the tr elements in the variable, but so far no go. Yes, you could do it like that if you don't mind using the xalan:nodeSet() extension function. Wrap the xsl:variable around the section of the code that creates the tr elements: <xsl:variable name="rows"> <xsl:choose> <xsl:when test="$gunk = 'x'"> <xsl:apply-templates select="myExt:method1(*)" mode="x" /> </xsl:when> <xsl:otherwise> <xsl:apply-templates select="myExt:method2(*)" mode="x" /> </xsl:otherwise> </xsl:choose> </xsl:variable> Now you can copy the $rows result tree fragment into the output with: <xsl:copy-of select="$rows" /> To count the number of tr elements that the result tree fragment contains, you have to convert the result tree fragment to a node set. The node set will consist of the root node of the result tree fragment, so you have to go down to its tr children to get the tr elements that you want to count: count(xalan:nodeSet($rows)/tr) But I don't think that technique is the best way to do it. Essentially, the number of rows that you're generating is the same as the number of nodes returned by whichever of the two extension methods is used. If you could store those nodes in a variable then you could first apply templates to them and then count them later on. The trouble is, of course, that you have different node sets in different situations. In most cases, you can get around this by adding predicates to the paths that you're using to access the nodes (in this case your extension function calls). The predicate holds the condition in which the nodes from that node set should be retrieved. In your case, you could do: myExt:method1(*)[$gunk = 'x'] | myExt:method2(*)[$gunk != 'x'] If $gunk equals 'x' then only the nodes returned by myExt:method1(*) are put in the node set; if it doesn't, then the only nodes are the ones from myExt:method2(*). Putting that together in your code, you should have something like: <table border="1"> <xsl:variable name="nodes" select="myExt:method1(*)[$gunk = 'x'] | myExt:method2(*)[$gunk != 'x']" /> <xsl:apply-templates select="$nodes" mode="x" /> </table> <xsl:value-of select="count($nodes)"/> rows generated. A big caveat on this is that the extension methods that you're using will both always be evaluated. One downside might be that the process is less efficient because both methods are called (it depends on how optimised the processor is, I guess). But a more major downside comes into play if the condition in the predicate involves testing whether the extension functions are available or not. For example, if you were doing: myExt:method1(*)[function-available('myExt:method1')] | myExt:method2(*)[function-available('myExt:method2')] then it would fail. But I don't think that's the situation in your case. 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] Conditional counting, Hunsberger, Peter | Thread | Re: [xsl] Conditional counting, Joerg Pietschmann |
Re: [xsl] html inside xml, David Carlisle | Date | Re: [xsl] Conditional counting, Joerg Pietschmann |
Month |