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

Re: Targeting nodes between <lb/> elements

Subject: Re: Targeting nodes between <lb/> elements
From: Chris von See <chris@xxxxxxxxxxxxx>
Date: Sun, 27 Apr 2008 21:47:13 -0700
Re:  Targeting nodes between <lb/> elements
I have a similar problem in that I have to process books which can have page markers at any level of the content. What I ended up doing was building a two-step process - one which reformats the text such that the "separators" (the <lb/> elements in your case) are all at the same level, and then a second step which performs the actual work needed (generating <fo:block>elements in your case). I had a common root element that I could work backwards to using the ancestor axis to close all of the open tags up to that point by writing closing tags with <xsl:text>; I then wrote my "separator" and then worked forward from that element using the same axis to re-open all of the previously-open tags using <xsl:text>. It's very rough and probably violates many principles of XSLT, but it works.

In essence, the logic is:

<xsl:template match="lb">
for each ancestor between current node and a common root node (working backwards from current node's parent to common root)
.. write a fake closing element node using <xsl:text: disable-output- escaping="true">
end for each


write <lb/> node

for each ancestor between current node and a common root node (working forwards from common root to current node's parent)
.. write a fake opening element node using <xsl:text: disable-output- escaping="true"> with note that generated open node is a "fake"
end for each
</xsl:template>


What you'd end up with as a result of this first step, based on your example, is:

<root>
<lb/>
<sp><speaker>speaker1</speaker><p>text1</p></sp>
<lb/>
<sp fake="yes"><p fake="yes">text2</p></sp>
<lb/>
<sp><speaker>speaker2</speaker><p>text3</p></sp>
<lb/>
<sp fake="yes"><p fake="yes">text4</p></sp>
<lb/>

This could then be processed pretty easily using <xsl:for-each- group>, which I think would look something like this (not tested):

<xsl:for-each-group select="*" group-starting-with="lb">
<fo:block>
<xsl:for-each select="current-group()">
... call templates to write <fo:inline> or text as appropriate ...
</xsl:for-each>
</fo:block>
</xs:for-each-group>

Your results may vary :)

I too would be interested to see if there's a more elegant, non- kludgy way of solving this problem.


Cheers Chris

On Apr 27, 2008, at 8:45 PM, xsl-list@xxxxxxxxxxxx wrote:
Hello all,

I've been lurking for a while, and would like first to express my thanks to all of the experts here who are so incredibly generous with their expertise.

I've been banging my head (painfully) against what seems to me should be a relatively simple issue. I've tried to find the solution in the obvious books and in the archives of this list, but at this point am completely demoralised by repeated failure. I'd be extremely grateful for any help in getting past this hurdle.

I'm trying to wrap in an <fo:block> the nodes between pairs of <lb/ > elements. These nodes are not all siblings:

[source]
<lb/><sp><speaker>speaker1</speaker><p>text1
<lb/>text2</p></sp>
<lb/><sp><speaker>speaker2</speaker><p>text3
<lb/>text4</p></sp>

[desired output]
<fo:block><fo:inline>speaker1</fo:inline>text1</fo:block>
<fo:block>text2</fo:block>
<fo:block><fo:inline>speaker2</fo:inline>text3</fo:block>
<fo:block>text4</fo:block>

Also, I need to be able to further process some elements in each matched sequence (such as the <speaker> shown in the example). None of these elements will contain <lb/>.

Using XSLT 2.0 and Saxon 9B (and XEP), I've tried countless approaches involving for-each-group or simple XPath predicates ( << and >> ). Problems have ranged from matching problems to looping problems (Saxon error: "Too many nested apply-templates calls. The stylesheet may be looping.").

Many thanks in advance for any help you can send my way. At this point I'm fully prepared to be mortified by the inevitable simplicity of the solution...

Kitto

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.