Re: [xep-support] Selecting everything "before" and "after" a given node

From: G. Ken Holman <>
Date: Mon Mar 30 2009 - 23:30:38 PST

At 2009-03-30 16:14 -0400, Harvey, Paul wrote:
>This one’s got me stumped, but perhaps it’s simpler than I think.

Not at all. This is in no way a simple problem,
but I do have a strategy for you to consider.

>We have XML something like this (this is very much simplified)
> <account>
> <bureau>
> <fund>
> <table>...</table>
> </fund>
> <fund>
> <table>...</table>
> </fund>
> </bureau>
> <bureau>
> <fund>
> <table>...</table>
> </fund>
> <fund>
> <table
> type=”BREAK-OUT”><!-- THIS NEEDS TO BE BROKEN OUT --></table>
> </fund>
> <fund>
> <table>...</table>
> </fund>
> </bureau>
> <bureau>
> <fund>
> <table>...</table>
> </fund>
> </bureau>
> </account>
> <account>...</account>
>In our XSL:FO we have (again simplified)
> <xsl:apply-templates/>
>But we have a special case now in which the
>table highlighted above needs to span two
>columns. To do this we need to put it in a block which is a child of the flow.
>Our existing template structure deeply nests
>stuff in blocks, wrappers and inlines, so we
>need to be able to break the table out by doing something along the lines of…
> <xsl:apply-templates select=”Nodeset of
> all nodes before the table in question”/>
> <fo:block span="all">
><xsl:apply-templates select=”//table[@type=’BREAK-OUT’]”/>
> </fo:block>
><xsl:apply-templates select=”Nodeset of all
>nodes after the table in question”/>
>Conceptually this seems reasonable enough, but
>in playing around with various axis
>(preceding/following/ancestor and unions thereof) I’ve not got it yet.

Nor will you in the general case. There are some
simple examples where users are able to unwind
their nested formatting objects once encountering
the table, and then rewinding them up again after
finishing the table in order to continue on with the following constructs.

And when using XSLT 2.0 there are simple examples
where users can use the new "<<" and ">>"
operators to act on those constructs that are
before and after a given construct in document
order. This would satisfy your "nodeset of all
nodes before/after the table in question", but
you have to be careful about which ones you
address so as not to repeat the nested apply-templates.

In these simple cases users can just process what
is before the special table, process the special
table, and then process what is after the special table.

>Does anyone have any suggestions, or is there a
>nice idiom for what I’m trying to do?
>By the way, the stylesheet is large and complex

Thus I'm assuming the simple case does not
apply. Just imagine trying to interrupt the
on-the-fly nested XSL-FO constructs, doin the
table, and then remembering and repeating all of
the algorithms that led up to the table in order
to restart the nested formatting objects.

I think it is untenable *at the time of doing the original formatting*.

>and I’m hoping to find away to select what I
>want and have existing code handle it, with a
>minimal of changes to existing code.

The idiom I've suggested to others, with *almost
zero* changes to the _existing_ code is to do a
second pass on the generated XSL-FO.

Remember that XSL-FO is tolerant of foreign
namespaces. Using your own namespace you can
seed signals in the XSL-FO document and the
processor would just ignore them. The only
change you add to your existing code is to add in
the XSL-FO a private foreign-namespace attribute
of your own to signal the table that needs to be spanned.

Generate the XSL-FO and you will have an XML
document that you can process with a new XSLT
stylesheet before sending it to the XSL-FO
engine. In this second pass you will be able to
detect the nested table. It isn't general
purpose, but you should be able to, upon
detection of the nested table, end off all of the
ancestral formatting objects, format the spanned
table, and then replay the start tags of the
ancestral formatting objects and continue with
the content after the table. You can take out
the magic attribute in the second pass or leave
it in since it won't disturb a conforming XSL-FO processor.

It could get uncomfortable if you are nested
inside of list items, but it wouldn't be impossible.

The nice thing about this approach is that you
don't have to replay the algorithms you had
before to generate the nesting formatting
objects, you only need to repeat the results of
the algorithms that you find in the generated XSL-FO instance.

One bad thing is that it isn't a single pass.

So this isn't a magic bullet that I can yet post
on Crane's web site (though I'm still trying to
think of a general solution to edge cases), but
when I stop my crazy traveling schedule and find
the time to sit down with this, I have an inkling
it might be possible to do in the almost general case.

I hope this helps.

. . . . . . . . . . Ken

XSL-FO/XSLT/XQuery training in Los Angeles (New dates!) 2009-06-08
Training tools: Comprehensive interactive XSLT/XPath 1.0/2.0 video
Video lesson:
Video overview:
G. Ken Holman       
Crane Softwrights Ltd.
Male Cancer Awareness Nov'07
Legal business disclaimers:
(*) To unsubscribe, send a message with words 'unsubscribe xep-support'
in the body of the message to from the address
you are subscribed from.
(*) By using the Service, you expressly agree to these Terms of Service
Received on Tue Mar 31 00:25:29 2009

This archive was generated by hypermail 2.1.8 : Tue Mar 31 2009 - 00:25:36 PST