Subject: RE: [xsl] Finding sequences of same element From: "Michael Kay" <mike@xxxxxxxxxxxx> Date: Wed, 9 Feb 2005 09:24:40 -0000 |
Search for "positional grouping" for solutions to this problem. Assuming you want a pure XSLT 1.0 solution, rather than one that relies on XSLT 2.0 for-each-group, or EXSLT extensions like set:leading(), a recursive template is probably the simplest approach. In fact, it's sometimes easier than using for-each-group. Remember that you can use apply-templates as well as call-template for such problems. Try this: <xsl:template match="A"> <xsl:copy> <xsl:apply-templates select="*"/> </xsl:copy> </xsl:template> <xsl:template match="A/*" priority="8"> <xsl:copy-of select="."/> </xsl:template> <xsl:template match="B[preceding-sibling::*[1][self::B]]" priority="15"/> <xsl:template match="B" priority="10"> <D> <xsl:apply-templates select="." mode="sequence"/> </D> </xsl:template> <xsl:template match="B" mode="sequence"> <xsl:copy-of select="."/> <xsl:apply-templates select="following-sibling::*[1][self::B]" mode="sequence"/> </xsl:template> The way to think about this is that you want to have a template rule for every element in the result tree, and then you want to organize your apply-templates to select the nodes in the input tree that will trigger creation of a node in the result tree. Michael Kay http://www.saxonica.com/ > -----Original Message----- > From: Simon Kissane [mailto:skissane@xxxxxxxxx] > Sent: 09 February 2005 07:59 > To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx > Subject: [xsl] Finding sequences of same element > > Hi > > Suppose I have an input document: > <A><B X="1"/><B X="2"/><B X="3"/><C X="4"/><B X="5"/><B > X="6"/><B X="7"/></A> > > Now, suppose I wish to group together consecutive B elements, giving a > result document like this: > <A><D><B X="1"/><B X="2"/><B X="3"/></D><C X="4"/><D><B X="5"/><B > X="6"/><B X="7"/></D></A> > > How can I do this? (I would prefer not to use recursive templates, but > rather for-each, if that is at all possible...) > > I think I can find the initial element of these sequences, like so: > B[not(preceding-sibling::*) or > preceding-sibling::*[0][not(self::B)]] > This, I think, should select all B for which there are either no > preceeding sibling elements, or for which the immediately preceeding > sibling element is not a B element. Thus, in the above example, it > would pick B[@X=1] and B[@X=5]. > > But, given each initial sequence element, how can I find the remaining > nodes in the sequence? With the initial sequence element as the > context node, I could do: > .|following-sibling::B > But that will also pick up B[@X=5] and B[@X=6] when the > context node is B[@X=1]. > > Is there a predicate test I could use on following-sibling::B to > restrict it only to the current sequence of B elements? > > Thanks > > Simon Kissane
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Finding sequences of same, Mukul Gandhi | Thread | Re: [xsl] Finding sequences of same, Dimitre Novatchev |
RE: [xsl] Can I use a boolean varia, Michael Kay | Date | [xsl] Addressing siblings, David.McKay |
Month |