xsl-list
[Top] [All Lists]

Re: [xsl] Getting text and non-block nodes before any block nodes

2014-09-15 08:33:34
Hi Eliot,

I would treat this as a special application of a more general problem,
namely grouping loose children that might have been wrapped, but
weren't. Such as splitting paragraphs around lists or other constructs
not permitted in paragraph analogues in the target.

So, select="node()" group-adjacent="cp:isBlock(.)" will return groups
that are either all blocks, or all not blocks.

Inside for-each-group, position() returns the position of the group
within all the groups, so you can use it to determine the first group.

But with all the groups given, plus
when/@test='current-grouping-key()" to determine whether it is (or
isn't) a group of blocks, much more is also possible.

Cheers, Wendell



On Fri, Sep 12, 2014 at 8:10 PM, G. Ken Holman 
g(_dot_)ken(_dot_)holman(_at_)gmail(_dot_)com
<xsl-list-service(_at_)lists(_dot_)mulberrytech(_dot_)com> wrote:
At 2014-09-12 21:50 +0000, Eliot Kimber ekimber(_at_)contrext(_dot_)com wrote:

I think this is an FAQ but my situation may be slightly different. In any
case, if it's an FAQ, maybe my asking it will help.

This is in a DITA context, where I can know for any element whether it is
a block or not a block (because in DITA all elements have a base type that
is inherently block or not block).

I have the situation where a wrapper element may contain any combination
of text, non-block elements, or block elements.

I need to find either all the nodes up to the first block or determine
that there are none and get the first block.


I think this will work:

  select="node()[. &lt;&lt; current()/*[lc:isBlock(.)][1]"

But it is XSLT 2.0 only.

For XSLT 1.0 I might do something like:

  select="node()[generate-id(following-sibling::*[lc:isBlock(.)][1]) =
                 generate-id(current()/*[lc:isBlock(.)][1])]"/>

Where the lc:isBlock() function returns true if the element provided is a
DITA block element.

This seems to pass all my tests but I'm wondering if there's a better way
to make this check?

I also realized that I can use the $textBeforeBlocks variable to then
process any remaining blocks (because I will have already output the text
before blocks):

<xsl:when test="$hasTextBeforeBlocks">
  <xsl:apply-templates select="node() except($textBeforeBlocks)"/>
        </xsl:when>


That includes the block element ... you might try using ">>" in a way
similar to how I used "<<" above if you didn't want to include the block
element itself.

I hope this helps!

. . . . . . Ken


--
Contact us for world-wide XML consulting and instructor-led training |
Free 5-hour lecture: http://www.CraneSoftwrights.com/links/video.htm |
Crane Softwrights Ltd.            http://www.CraneSoftwrights.com/s/ |
G. Ken Holman                   
mailto:gkholman(_at_)CraneSoftwrights(_dot_)com |
Google+ profile:      http://plus.google.com/+GKenHolman-Crane/about |
Legal business disclaimers:    http://www.CraneSoftwrights.com/legal |


---
This email is free from viruses and malware because avast! Antivirus
protection is active.
http://www.avast.com





-- 
Wendell Piez | http://www.wendellpiez.com
XML | XSLT | electronic publishing
Eat Your Vegetables
_____oo_________o_o___ooooo____ooooooo_^
--~----------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
EasyUnsubscribe: http://lists.mulberrytech.com/unsub/xsl-list/1167547
or by email: xsl-list-unsub(_at_)lists(_dot_)mulberrytech(_dot_)com
--~--

<Prev in Thread] Current Thread [Next in Thread>