This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Newbie question - grouping and subtotaling


Hi Sai,

> e.g., if one tries to introduce an xml:key element, one cannot use
> variables - isn't this a pain? I mean - if I wanted to write a
> generic XSLT that could take any XML file with the appropriate data
> structure, shouldn't I be able to apply a generic transform to
> convert it to another look? Isn't that the function of XSLT?

Yes, it's a pain that you can't use variable references in xsl:key.
And yes, XSLT should be able to transform your XML into any text-based
format that you want, and it can. But what you're trying to do is to
have some XML that controls or describes the transformation that the
XSLT does and have XSLT interpret that to change the way that it
structures the XML. That's more difficult.

Probably the easiest and best way to approach this is to use the
meta-transformation XML (the group_params element and its contents) to
generate an XSLT stylesheet that you then use on the source data (the
book elements in this context) to do the grouping and subtotalling. In
other words, have a stylesheet that creates a stylesheet holding the
xsl:key elements that you need based on the values of the
category_level elements. You'll need to look at xsl:namespace-alias
when creating the stylesheet-that-creates-a-stylesheet.

The other way to do it would be to use:

<xsl:key name="groups"
         match="*[name() = /catalog/group_params/outer_category]"
         use="concat(*[name() =
                       /catalog/group_params/category_level1], '::',
                     *[name() =
                       /catalog/group_params/category_level2])" />

Elsewhere of course you *can* use variable references, so you could
then do the grouping by getting elements with unique values using
expressions like:

  *[generate-id() =
    generate-id(key('groups',
                    concat(*[name() = $category_level1], '::',
                           *[name() = $category_level2]))[1])]

And similarly to get the sum:

  sum(key('groups', concat(*[name() = $category_level1], '::',
                           *[name() = $category_level2]))
      /*[name() = $subtotal])
                           
Of course this gets very complicated if the number of categories that
you're using isn't fixed. You could substitute the *[name() = $foo]
constructions with a dynamic evaluation, e.g. saxon:evaluate($foo) for
simplicity, although it's likely to actually be less efficient I
think, because of the run-time parsing and evaluation of the XPath.

You never know, this might get easier when we have proper grouping
instructions in XSLT 2.0...

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]