[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] Re: Using an empty xsl:for-each statement to "touch"
The way the spec is written (I'll go on to the Saxon implementation later) you shouldn't need to "touch" the elements. Looking at the draft here: http://www.w3.org/TR/2013/WD-xslt-30-20131212/ You should be able to do > <xsl:template match="purchase-order"> > <Total-Cost> > <xsl:value-of select="accumulator-after('f:item-cost')"/> > </Total-Cost> > </xsl:template> which is the equivalent of > <xsl:template match="purchase-order"> > <Total-Cost> > <xsl:value-of select="f:total-item-cost()"/> > </Total-Cost> > </xsl:template> in the 2012 draft. The reason this works is that the xsl:value-of qualifies as both a pre-descent and a post-descent instruction, because it has no consuming instruction as either a preceding or a following sibling. I dare say this almost certainly doesn't work in Saxon 9.5, where as you suggest you will probably have to inject a consuming instruction into the template before you can get the post-descent value of the accumulator. You could for example write <xsl:sequence select="nothing"/>. Michael Kay Saxonica On 12 Dec 2013, at 10:40, Costello, Roger L. <costello@xxxxxxxxx> wrote: > Hi Folks, > > Suppose you want to add together all the costs in this purchase order: > > <purchase-order> > <item> > <cost>10</cost> > </item> > <item> > <cost>20</cost> > </item> > <item> > <cost>19</cost> > </item> > <item> > <cost>25</cost> > </item> > <item> > <cost>17</cost> > </item> > </purchase-order> > > The new XSLT 3.0 accumulator can be used. The accumulator is updated each time a <cost> element is "touched". To "touch" each <cost> element I have this empty loop: > > <xsl:for-each select="item"> > <xsl:for-each select="cost"/> > </xsl:for-each> > > That inner loop doesn't need any statements because its sole purpose is merely to "touch" the cost element, and thereby trigger the accumulator to be updated. > > Here is the XSLT program with the accumulator: > > <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > xmlns:xs="http://www.w3.org/2001/XMLSchema" > exclude-result-prefixes="#all" > version="3.0"> > > <xsl:output method="xml" /> > > <xsl:accumulator name="f:item-cost" > post-descent="f:total-item-cost" > as="xs:integer" > initial-value="0"> > <xsl:accumulator-rule match="cost" new-value="$value + xs:integer(.)"/> > </xsl:accumulator> > > <xsl:template match="purchase-order"> > <Total-Cost> > <xsl:for-each select="item"> > <xsl:for-each select="cost"/> > </xsl:for-each> > <xsl:value-of select="f:total-item-cost()" /> > </Total-Cost> > </xsl:template> > > </xsl:stylesheet> > > I realize that this problem could be solved in other ways, but I wanted to show how it could be solved using an accumulator. And that invariably led me to an empty xsl:for-each statement. > > Is there a better way to "touch" an element than using an empty xsl:for-each statement? > > /Roger
|
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
|