Re: [xsl] Preceding siblings test

Subject: Re: [xsl] Preceding siblings test
From: Hermann Stamm-Wilbrandt <STAMMW@xxxxxxxxxx>
Date: Tue, 14 Sep 2010 19:15:18 +0200
Based on Martin's solution this is for XSLT 1.0:
Below use of generate-id() seems being able to emulate ">>".

$ xsltproc pre.xsl list.xml


<item>...</item><a/>

<item>...</item><b/><b/><a/>
<item>...</item>

<item>...</item><a/><a/>

$ cat list.xml
<list>
<a/>
<item>...</item>
<b/><b/><a/>
<item>...</item>
<item>...</item>
<a/><a/>
<item>...</item>
</list>
$
$ cat pre.xsl
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
>
  <xsl:output omit-xml-declaration="yes" />

   <xsl:template match="item">
     <xsl:variable name="preceding-item-id"
       select="generate-id(preceding-sibling::item[1])"/>
     <xsl:variable name="preceding-abs"
       select="(preceding-sibling::a|preceding-sibling::b)
               [$preceding-item-id = generate-id(preceding::item[1])]"/>

     <xsl:copy-of select="."/>
     <xsl:copy-of select="$preceding-abs"/>
   </xsl:template>

</xsl:stylesheet>
$


Mit besten Gruessen / Best wishes,

Hermann Stamm-Wilbrandt
Developer, XML Compiler, L3
Fixpack team lead
WebSphere DataPower SOA Appliances
----------------------------------------------------------------------
IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats: Martin Jetter
Geschaeftsfuehrung: Dirk Wittkopp
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294



From:       Martin Honnen <Martin.Honnen@xxxxxx>
To:         xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Date:       09/14/2010 05:23 PM
Subject:    Re: [xsl] Preceding siblings test



Hintz, David wrote:

> I'm still a novice at XSLT and am having a problem coming up with a test
for elements preceding a particular element, but only up to the first
occurrence of the same (or parent) element.  For example, in this XML:
>
> <list>
> <a/>
> <item>...</item>
> <b/><b/><a/>
> <item>...</item>
> <item>...</item>
> <a/><a/>
> <item>...</item>
> </list>
>
> Assume in this example, <a> and <b> elements can occur before each item
(any number of each).  When I start processing an <item>, how do I get a
list of just those nodes before the first preceding <item> or parent <list>
element?

With XSLT 2.0 you can use the XPath 2.0 '>>' operator
   <xsl:template match="item">
     <xsl:variable name="preceding-item"
select="preceding-sibling::item[1]"/>
     <xsl:variable name="preceding-abs" select="preceding-sibling:a[.
&gt;&gt; $preceding-item] | preceding-sibling:b[. &gt;&gt;
$preceding-item]"/>
   </xsl:template>

It sounds however as if you might want to consider
   <xsl:for-each-group select="*" group-ending-with="item">
in a template matching the "list" element. That's also XSLT 2.0 however.




--

             Martin Honnen
             http://msmvps.com/blogs/martin_honnen/

Current Thread