Re: [xsl] block selection question (XSLT 1.0)

Subject: Re: [xsl] block selection question (XSLT 1.0)
From: Hermann Stamm-Wilbrandt <STAMMW@xxxxxxxxxx>
Date: Sat, 7 May 2011 11:44:58 +0200
Thank you all for the different solutions.

I tested the three XSLT 1.0 solutions and they work fine.
It is really interesting, how many different approaches are possible:
* sibling recursion
* closing tag counting (XPath)
* grouping by xsl:key

Also the current-group XSLT 2.0 approach is good to know.


Mit besten Gruessen / Best wishes,

Hermann Stamm-Wilbrandt
Developer, XML Compiler, L3
Fixpack team lead
WebSphere DataPower SOA Appliances
https://www.ibm.com/developerworks/mydeveloperworks/blogs/HermannSW/
----------------------------------------------------------------------
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:   05/06/2011 11:45 AM
Subject:        Re: [xsl] block selection question (XSLT 1.0)



Hermann Stamm-Wilbrandt wrote:

> I know that this is basic but I cannot get it done correctly.
>
> Input:
> <lines>
>    <line></line>
>    <line>A1</line>
>    <line>1</line>
>    <line>B1</line>
>    <line></line>
>    <line>A2</line>
>    <line>2</line>
>    <line>2</line>
>    <line>2</line>
>    <line>B2</line>
>    <line></line>
>    <line></line>
> </lines>
>
> Intended output (blockwise, start at A, all including next B):
> <line>A1</line>
> <line>1</line>
>
> <line>A2</line>
> <line>2</line>
> <line>2</line>
> <line>2</line>


The following stylesheet outputs the above result:

<xsl:stylesheet
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
   version="1.0">

   <xsl:output indent="yes"/>

   <xsl:key name="k1"
     match="line[not(starts-with(., 'A')) and not(starts-with(. , 'B')) 
and node()]"
     use="generate-id(preceding-sibling::line[starts-with(., 'A')][1])"/>

   <xsl:template match="@* | node()" name="identity">
     <xsl:copy>
       <xsl:apply-templates select="@* | node()"/>
     </xsl:copy>
   </xsl:template>

   <xsl:template match="lines">
     <xsl:apply-templates select="line[starts-with(., 'A')]"/>
   </xsl:template>

   <xsl:template match="line[starts-with(., 'A')]">
     <xsl:call-template name="identity"/>
     <xsl:apply-templates select="key('k1', generate-id())"/>
   </xsl:template>

</xsl:stylesheet>

I am however not sure whether the condition used
   "and node()"
is what you want.


-- 

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

Current Thread