[XSL-LIST Mailing List Archive Home]
[Reply To This Message]
Re: Selecting all nodes between pairs of <br> tags
Subject: Re: Selecting all nodes between pairs of <br> tags|
From: Duncan Anker <danker@xxxxxxxxxxxxx>
Date: Tue, 20 Jun 2006 13:55:37 +1000
Thank you very much for that. It looks a bit more elegant than what I
had started coming up with - I think because most similar solutions
involve xsl:for-each, I stopped thinking about recursion. Now I'm having
flashbacks of my brief experience with Prolog many years ago :)
I think I can probably get something working shortly, although I am
still seeing the issue where the nodeset is being processed after the
template call. What I mean by that is <br><br><b>A</b>B<br><br> will
output <!-- result from template call --><br><b>A</b>B<br> and I would
like the template to continue from after the 2nd <br> pair, not from the
point it was at when the call was made.
Is there a convenient way to skip the processed nodes, or is the
solution another template which matches each item in the list to
suppress it - this seems like it would suffer from the same problem though.
<xsl:param name="nodeset" />
<xsl:if test="not((local-name($nodeset) = 'br') and
(local-name($nodeset) = 'br'))">
<!-- do something with the node; i.e $nodeset -->
<xsl:with-param name="nodeset" select="$nodeset[position > 1]" />
I could not give this code earlier because your source XML data was
not enough for me to formulate this solution.
On 6/16/06, Duncan Anker <danker@xxxxxxxxxxxxx> wrote:
I am still having trouble grasping some of the more subtle points of
XPath. Consider the following HTML:
Following the advice of Mukul Gandhi given me a few weeks ago, I use
match="br[local-name(preceding-sibling::node()) = 'br']" (I am
using xsltproc with the --html option, which I suspect is normalizing
the spaces so this is slightly modified from the sample given):
I then select the nodes following with
select="following-sibling::node()[normalize-space != '']" - this is then
passed into a template which which outputs the A and B elements (I
handle these explicitly, which may be cheating, because I can't figure
out how to stop at <br> and I know the format of the data).
This is all well and good, except that my output comes out like this:
Currently, the selection of following siblings seems to select up to the
3rd <br> pair. This in itself is slightly odd, since I would have
thought it would select everything following at the same level, although
it appears to stop at the div tag, so perhaps the match ends there for
some pre-determined reason. In any case, I would like it to stop at the
second <br> tag pair - it seems like using a following-sibling rule
inside a predicate won't work easily since elements after the 2nd <br>
pair are followed by the 3rd <br> pair, so would still be included.
There must be some way to specify all following siblings up to <br><br>
and excluding anything after the <br><br> but the thought of what that
expression might look like is making my eyes glaze.
The other problem is the labels being output afterwards - it would seem
that this is matching where the previous template leaves off. I don't
understand why it outputs only the label and not the following data. Any
The relevant template:
<xsl:template match="br[local-name(preceding-sibling::node()) =
select="following-sibling::node()[normalize-space() != '']" />
<xsl:param name="nodeset" />
<xsl:for-each select="$nodeset[position() mod 2 = 1]">
<label><xsl:value-of select="." /></label>
Thanks in advance.
PURCHASE STYLUS STUDIO ONLINE TODAY!
Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!
Download The World's Best XML IDE!
Accelerate XML development with our award-winning XML IDE - Download a free trial today!
Subscribe in XML format