[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

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

Subject: Re: [xsl] Getting text and non-block nodes before any block nodes
From: "Wendell Piez wapiez@xxxxxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Mon, 15 Sep 2014 13:33:19 -0000

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.ken.holman@xxxxxxxxx
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:
> At 2014-09-12 21:50 +0000, Eliot Kimber ekimber@xxxxxxxxxxxx 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@xxxxxxxxxxxxxxxxxxxx |
> 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

Current Thread