This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: select following-siblings, but not all of them
- To: xsl-list at lists dot mulberrytech dot com
- Subject: Re: [xsl] select following-siblings, but not all of them
- From: Francis Norton <francis at redrice dot com>
- Date: Tue, 19 Dec 2000 13:47:19 +0000
- References: <3A3F5BD8.7327392E@debis.com>
- Reply-To: xsl-list at lists dot mulberrytech dot com
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