Re: [xsl] select following-siblings, but not all of them

Subject: Re: [xsl] select following-siblings, but not all of them
From: Francis Norton <francis@xxxxxxxxxxx>
Date: Tue, 19 Dec 2000 13:47:19 +0000

Matthias Häußer wrote:
> 
> ...
> I get far too much. Can I somehow restrict the selection to
> "the following siblings, up to the first occurence whose name
> is not 'remark' "?
> 
good post - sample input, desired output and faulty transform included -
makes it *so* tempting!

for input 

<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<name>Tom</name>
<remark>1</remark>
<remark>2</remark>
<remark>3</remark>

<name>John</name>
<remark>4</remark>
<remark>5</remark>
<remark>6</remark>

</dataset>

use the following transform:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
  <xsl:output method="text" version="1.0" indent="yes"/>
  <xsl:template match="/">
    <xsl:for-each select="/dataset/name">
      <xsl:variable name="key" select="."/>
      <xsl:value-of select="concat(., ' ')"/>
      <!-- get all following remark elements for which this is the
nearest preceding name -->
      <xsl:for-each
select="following-sibling::remark[count(preceding-sibling::name[1] |
$key) = 1]">
        <xsl:value-of select="concat(., ' ')"/>
      </xsl:for-each>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>


though if you *know* that each name element will have a unique value you
could replace 

	[count(preceding-sibling::name[1] | $key) = 1]

with

	[preceding-sibling::name[1] != $key]

You may not be familiar with the "count(x | y) = 1" idiom - because the
result of the "|" operator is a set containg the nodes on either side
with no duplicates, this can be used to test if two nodes are identical.

Francis.

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


Current Thread