[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Selecting all nodes between pairs of <br> tags

Subject: Selecting all nodes between pairs of <br> tags
From: Duncan Anker <danker@xxxxxxxxxxxxx>
Date: Fri, 16 Jun 2006 15:21:20 +1000
anker labels
Hi List,

I am still having trouble grasping some of the more subtle points of XPath. Consider the following HTML:

...
<br><br>
<b>A</b>B<br>
...
<br><br>
C
<br><br>
<div>
...

Following the advice of Mukul Gandhi given me a few weeks ago, I use match="br[local-name(preceding-sibling::node()[1]) = 'br'][1]" (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:

<ul>
<li><label>A</label>B</li>
...
<li><label>C</label></li>
<b>A</b><br> ...

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 suggestions?

The relevant template:

<xsl:template match="br[local-name(preceding-sibling::node()[1]) = 'br'][1]">

<ul>

<xsl:call-template name="stat">

<xsl:with-param name="nodeset"

select="following-sibling::node()[normalize-space() != '']" />

</xsl:call-template>

</ul>

</xsl:template>

<xsl:template name="stat">

<xsl:param name="nodeset" />

<xsl:for-each select="$nodeset[position() mod 2 = 1]">

<li>

<label><xsl:value-of select="." /></label>

<xsl:value-of select="normalize-space(following-sibling::text())" />

</li>

</xsl:for-each>

</xsl:template>


Thanks in advance. Duncan

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.