Re: [xsl] Finding nodes between other nodes

Subject: Re: [xsl] Finding nodes between other nodes
From: Mukul Gandhi <gandhi.mukul@xxxxxxxxx>
Date: Fri, 23 Apr 2010 21:27:51 +0530
On Fri, Apr 23, 2010 at 7:09 PM, Nic Gibson <nicg@xxxxxxxxxx> wrote:
> I'm trying to find all processing instructions that occur between the current
> node (which will always be a text node in this case) and the next text node
> (in document order).

Here's a rather different way of solving this. This uses,
xsl:for-each-group & is illustrated with an example. This is not a
pure XPath 2 solution, but uses few XSLT 2.0 instructions.

If the input document is following:

<x>
 <?a val1?>
 aaa
 <?b val2?>
 <?c val3?>
 bbb
 <?d val3?>
</x>

And the stylesheet is:

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

  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />

  <xsl:template match="/">
    <xsl:variable name="start-node" select="//text()[normalize-space()
= 'aaa']" />
    <xsl:for-each-group select="$start-node/following::node()"
group-ending-with="text()[not(normalize-space() = '')]">
      <xsl:if test="position() = 1">
        <xsl:copy-of select="current-group()[not(normalize-space() =
'')][position() lt last()]" />
      </xsl:if>
    </xsl:for-each-group>
  </xsl:template>

</xsl:stylesheet>

Then, the output produced by the above transform is:

<?b val2?><?c val3?>

Here are the key elements in the above stylesheet:
1) The variable, start-node is the text node, from where we need to
move forward. I use the check, normalize-space() = ... because, I do
not consider white-space nodes as significant.
2) The xsl:for-each-group does the grouping, and we print the 1st
group, which I think is the expected output.
3) We do not print the last element in the group (because, that is the
group boundary, and is after the last PI of the group nodes), which is
accomplished by the predicate, [position() lt last()].
4) xsl:copy-of is just for illustration. If an indented output is
needed, then the nodes can be printed with a xsl:for-each instruction.


-- 
Regards,
Mukul Gandhi

Current Thread