Re: [xsl] Process following siblings that have no text into children.

Subject: Re: [xsl] Process following siblings that have no text into children.
From: Michael Müller-Hillebrand <mmh@xxxxxxxxx>
Date: Wed, 15 Aug 2012 18:20:00 +0200
Richard,

Because I like to test stuff using Kernow [1] so much, I came up with this
little template for <sheet>:

<xsl:template match="sheet">
  <result name="{@name}">
    <xsl:for-each-group select="row" group-starting-with="row[column[1][. !=
'']]" >
      <item row="{@row}" name="{column[1]}">
        <xsl:for-each select="current-group()">
          <sub-item value="{column[3]}"/>
        </xsl:for-each>
      </item>
    </xsl:for-each-group>
  </result>
</xsl:template>

It requires XSLT2, but who would like to do without it?

BTW, your XML example was missing the closing </item> elements.

- Michael

[1]: http://kernowforsaxon.sourceforge.net

Am 15.08.2012 um 16:54 schrieb Kerry, Richard:

> ... this is what I really needed to ask in my query from yesterday ...
>
> I have Xml corresponding to part of a spreadsheet, like this :
>
> <sheet name="sheet-1" >
> <row row="6">
> <column column="1" cell="A6">Reference Present</column>
> <column column="2" cell="B6">1,2</column>
> <column column="3" cell="C6">1=missing</column>
> </row>
>
> <row row="7">
> <column column="1" cell="A7"/>
> <column column="2" cell="B7"/>
> <column column="3" cell="C7">2=present</column>
> </row>
>
> <row row="8">
> <column column="1" cell="A8">Reference Standard</column>
> <column column="2" cell="B8">0-11</column>
> <column column="3" cell="C8">0=missing</column>
> </row>
>
> <row row="9">
> <column column="1" cell="A9"/>
> <column column="2" cell="B9"/>
> <column column="3" cell="C9">1=525</column>
> </row>
>
> <row row="10">
> <column column="1" cell="A10"/>
> <column column="2" cell="B10"/>
> <column column="3" cell="C10">2=625</column>
> </row>
> </sheet>
>
> What I want to do is to make all the elements that have no text children of
the most recent one which does have text (as well as getting its own column[3]
put into a child).
>
> The result I want is as follows:
>
> <result name="sheet-1" >
> <item row="6" name="Reference Present" >
>    <sub-item value="1=missing" />
>    <sub-item value="2=present" />
> <item row="8" name="Reference Standard" >
>    <sub-item value="0=missing" />
>    <sub-item value="1=525" />
>    <sub-item value="2=625" />
> </result>
>
> The text from cells C6 and C7 have been used for the sub-item elements which
have been created as children of the item corresponding to row 6 (and A6)
> and that from cells C8, C9 and C10 have been used for the sub-item elements
which have been created as children of the item corresponding to row 8 (and
A8).
>
> At the moment I've got the following template in my stylesheet :
>
> <xsl:template match="row[column[1] != '']">
> <test-1 row="{@row}" value="{column[3]}" >
>    <xsl:variable name="axis" select="following-sibling::element()" />
>    <xsl:apply-templates select="$axis" mode="col-1"></xsl:apply-templates>
> </test-1>
> </xsl:template>
>
> (I have another template to catch "row" with no text in column 1, and one
for "row" with mode=col-1. )
>
> This matches every "row" which does have text in column[1].
> It then applies the mode=col-1 template on every following-sibling.
>
> However, that of course runs to the end of the document.  I only actually
want it to run up to, but not including, the next "row" with non-null text.
>
> Please can someone advise what the best way of achieving this would be ?
> Do I need just to do a search along $axis for the first non-null text, save
the position in a variable, then use that to select the length of a
subsequence of $axis ?
> Or is there a neater way of doing the job ?  Can I get the sequence up to
the next following sibling with non-null text in a single call ?
>
>
> Puzzledly,
> Richard.

Current Thread