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

G. Ken Holman gkholman at CraneSoftwrights.com
Tue Mar 31 00:30:38 PDT 2009


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)
>
><chapter>
>       <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>
></chapter>
>
>In our XSL:FO we have (again simplified)
>
>...
><fo:flow>
>    <xsl:apply-templates/>
></fo:flow>
>...
>
>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

>
>...
><fo:flow>
>       <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”/>
></fo:flow>
>...
>
>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:    http://www.youtube.com/watch?v=PrNjJCh7Ppg&fmt=18
Video overview:  http://www.youtube.com/watch?v=VTiodiij6gE&fmt=18
G. Ken Holman                 mailto:gkholman at CraneSoftwrights.com
Crane Softwrights Ltd.          http://www.CraneSoftwrights.com/f/
Male Cancer Awareness Nov'07  http://www.CraneSoftwrights.com/f/bc
Legal business disclaimers:  http://www.CraneSoftwrights.com/legal


-------------------
(*) To unsubscribe, send a message with words 'unsubscribe xep-support'
in the body of the message to majordomo at renderx.com from the address
you are subscribed from.
(*) By using the Service, you expressly agree to these Terms of Service http://www.renderx.com/terms-of-service.html



More information about the Xep-support mailing list