Re: [xsl] How to render TEI <div*>s with chapter-like pagination?

Subject: Re: [xsl] How to render TEI <div*>s with chapter-like pagination?
From: Wendell Piez <wapiez@xxxxxxxxxxxxxxxx>
Date: Tue, 15 Apr 2003 11:26:54 -0400
James,

At 07:25 PM 4/14/2003, you wrote:
Turns out that the above doesn't *quite* work because
a  div1 may have a sibling that is a div1. Easy enough
problem to fix, though, at least by a combination of
"for-each" and "if".

Not the best way to go about fixing though. Set up the key to be what you actually want.


In your case, my guess it'll probably be something along the lines of:

<xsl:key name="top-levels-by-div"
         match="body/*[not(starts-with(local-name(), div))]"
         use="generate-id((preceding-sibling::div|preceding-sibling::div0|preceding-sibling::div1)[last()])"/>

It matches all child elements of body that are not themselves divs, and uses as the key value the generated id of the most recent div, div0 or div1.

div2, div3 etc. we don't have to worry about since they can't occur at the top level.

If you never had div0 or div1 (ie if your source were normalized to plain divs), this could be

<xsl:key name="top-levels-by-div"
         match="body/*[not(self::div)]"
         use="generate-id(preceding-sibling::div[1])"/>

Assuming this case (since it's simpler) your implementation pattern would be:

<xsl:template match="body">
  <fo:page-sequence>
    <xsl:apply-templates select="key('top-levels-by-div','')"/>
    <!-- gets top-level nodes not preceded by a div -->
  </fo:page-sequence>
  <xsl:apply-templates name="div"/>
</xsl:template>

<xsl:template match="div">
  <fo:page-sequence>
    <xsl:apply-templates/>
    <!-- invite the kids -->
    <xsl:apply-templates select="key('top-levels-by-div', generate-id())"/>
    <!-- invite the orphan nodes that directly follow this div -->
  </fo:page-sequence>
</xsl:template>

Still, I wish I knew why

<xsl:key name="x"
match="node()[not(starts-with(name(), div))]"
use="generate-id((..|preceding-sibling::div1|
preceding-sibling::div2|preceding-sibling::div3)[last()])"/>
doesn't work

The nodes you're worried about (nodes under body, perhaps under front or back, which I've left out of scope) won't have preceding siblings that are div2 or div3, since the only kinds of divs allowed there are div, div0 or div1. (This is a design flaw, IMHO, but there you are; the TEI as so often is trying to be ecumenical.)


If your top-level divs are div0s, this key won't match a milestone element to the div0 that directly precedes it ... etc. etc.

(And you'll have to forgive David for not having memorized the TEI DTD; I think MathML is probably enough of an accomplishment.)

doesn't work, or why the following doesn't do what the
xsl:key line you gave me does:

<xsl:key name="x"  match="node()"
use="generate-id(..|preceding-sibling::div1[1]|
preceding-sibling::div2[1]|preceding-sibling::div3[1])"/>

The generated id here belongs to the *first* (in document order) of either the parent, most immediately preceding div1, div2 or div3. You want the most recent one. The explanation for why this is may be found in an XPath manual that explains that when generate-id() is used on a node set, it returns the generated id for the first node in the set in document order. You want the generated id of the last.


I hope that helps. If confusion persists, perhaps we should mock up a mini-sample instance to demonstrate the problem. Or maybe three of them: one for each kind of top-level div.

Cheers,
Wendell


====================================================================== Wendell Piez mailto:wapiez@xxxxxxxxxxxxxxxx Mulberry Technologies, Inc. http://www.mulberrytech.com 17 West Jefferson Street Direct Phone: 301/315-9635 Suite 207 Phone: 301/315-9631 Rockville, MD 20850 Fax: 301/315-8285 ---------------------------------------------------------------------- Mulberry Technologies: A Consultancy Specializing in SGML and XML ======================================================================


XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list



Current Thread