Re: [xsl] Best Way to Break Up Nested Structures Based On Inline Elements

Subject: Re: [xsl] Best Way to Break Up Nested Structures Based On Inline Elements
From: "Imsieke, Gerrit, le-tex gerrit.imsieke@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 18 Apr 2018 18:15:48 -0000
Hi Eliot,

I think this can be tackled with what I call "upward projection", see for ex. https://markmail.org/message/kmq2g4fidmw6cofz

You'd identify all leaf elements and group them (maybe a combination of group-starting-with="two-colum-start" and group-ending-with="two-colum-end" is in order here).

Then for each group you transform the top-level block in a certain mode, with a tunneled parameter. The tunneled parameter contains the current group and its ancestors.

In the template that matches any element in this mode, you check whether the tunneled parameter contains the current element. If so, the next-match identity template will apply, if not, nothing will be written to the result.

There's a special template in this mode that matches the two-column-start element. It will create <fo:block span="none"> and then go on processing the children.

I'm not 100% sure whether this works, but I have an intercontinental flight ahead of me. It will give me some time to create working code, unless you're faster implementing the suggested solution (or a better one).

I guess that the solution scales with the number of splitting points times the number of leaves, so performance may deteriorate for large documents with frequently changing column spans.

Gerrit

On 18/04/2018 19:45, Eliot Kimber ekimber@xxxxxxxxxxxx wrote:
Using XSLT 2 with Saxon.

In the context of generating XSL-FO markup where there tree of fo:block elements can be quite deep, I need to break the blocks into a sequence of top-level blocks that specify @span based on the presence of markers anywhere in the heirarchy. This is to support FOP's strict implementation of the FO spec, which only allows specifying column spans on direct children of fo:flow.

In my processing I'm emitting marker elements to signal the starts and ends of areas that need to change the column spanning, e.g.:

<fo:block span="all">
   <fo:block>
      <fo:block>
        <fo:block>
           <two-column-start/>
       </fo:block>
       ...
      <two-column-end/>
    </fo:block>
   <fo:block>...
   </fo:block>
</fo:block>

Where the result needs to be:

<fo:block span="all">
    <!-- Stuff before two-column start -->
</fo:block>
<fo:block span="none">
    <!-- Stuff up to <two-column-end/> marker -->
</fo:block>
<fo:block span="all">
   <!-- Stuff after <two-column-end> marker -->
</fo:block>

There must be a general pattern for solving this kind of transformation pattern but I'm not seeing it or not remembering it.

I can think of a recursive algorithm to do it but is there a simpler or more efficient approach? Conceptually it's a for-each-group problem but the structure of the content doesn't see to lend itself to grouping.

Thanks,

Eliot
--
Eliot Kimber
http://contrext.com




-- Gerrit Imsieke GeschC$ftsfC<hrer / Managing Director le-tex publishing services GmbH Weissenfelser Str. 84, 04229 Leipzig, Germany Phone +49 341 355356 110, Fax +49 341 355356 510 gerrit.imsieke@xxxxxxxxx, http://www.le-tex.de

Registergericht / Commercial Register: Amtsgericht Leipzig
Registernummer / Registration Number: HRB 24930

GeschC$ftsfC<hrer / Managing Directors:
Gerrit Imsieke, Svea Jelonek, Thomas Schmidt

Current Thread