|
Subject: Re: [xsl] empty elements to filled without overlapping hierachies From: James Cummings <James.Cummings@xxxxxxxxxxxxxx> Date: Thu, 13 Nov 2003 11:23:49 +0000 (GMT) |
On Wed, 12 Nov 2003, Jeni Tennison wrote:
> Let's try to find an XSLT 2.0 solution. It will use
> <xsl:for-each-group> with the group-starting-with option, which groups
> together items such that each group starts with the same thing.
This works, though I'm confused about one tiny bit, I'll mention further down, but
let me make sure I understand how it is working first. (I do
*try* and learn rather than just leech your generous help...I'm just
not always that good at it ;-) )
> The first level of grouping is <SN>s. We want to group all the
> child nodes of the <body> element, aside from the <TITLE> element,
> into groups that start with a particular <SN> element. For each of
> these groups, we want to create a <SN> element with the value
> attribute from the original <SN>:
>
> <xsl:template match="body">
> <body>
> <xsl:copy-of select="TITLE" />
> <xsl:for-each-group select="node() except TITLE"
> group-starting-with="SN">
> <SN value="{@value}">
> ...
> </SN>
> </xsl:for-each-group>
> </body>
> </xsl:template>
So this takes any node() which includes the child elements and
any text() nodes and groups them together (except for TITLE)
as starting with SN. I've never used @group-starting-with
before that does seem very handy.
> Next, we want to take the elements in that group (aside from the <SN>
> element itself) and group them into groups starting with <Q> elements.
> Now, there are three possible arrangements of these groups:
>
> 1. The very first group might not start with a <Q> element; in that
> case, we just want to copy all the items in that group.
>
> 2. The group might end with a <SSD> element, in which case we want
> to have a <Q> element that contains all the items in the group
> aside from that final <SSD> element (and the <Q> element itself).
>
> 3. The group might end with something other than a <SSD> element, in
> which case we want to have a <Q> element that contains all the
> items in the group aside from the <Q> element itself
>
> <xsl:template match="body">
> <body>
> <xsl:copy-of select="TITLE" />
> <xsl:for-each-group select="node() except TITLE"
> group-starting-with="SN">
> <SN value="{@value}">
> <xsl:for-each-group select="current-group() except ."
> group-starting-with="Q">
except .in this context being whatever is in group-starting-with above?
> <xsl:choose>
> <xsl:when test="not(self::Q)">
> <xsl:copy-of select="." />
> </xsl:when>
So case 1 above, copy anything that isn't Q
> <xsl:when test="current-group()[last()][self::SSD]">
> <Q value="{@value}">
> <xsl:copy-of select="(current-group() except .)
> [position() != last()]" />
> </Q>
> <xsl:copy-of select="current-group()[last()]" />
> </xsl:when>
So case 2 above, close the Q before the last SSD - this is where
my real question is. If I don't include <xsl:strip-space
elements="body" /> This doesn't work right so you get:
<Q value="foo">blah blah blah
<SSD value="blah"/></Q>
instead of
<Q value="foo">blah blah blah
</Q><SSD value="blah"/>
but I'm not confident about what that is. Is it because the
original might have had something like:
<Q value="foo"/>blah blah blah
<SSD value="blah"/>
[whitespacenode]
Or am I misunderstanding that?
> <xsl:otherwise>
> <Q value="{@value}">
> <xsl:copy-of select="current-group() except ." />
> </Q>
> </xsl:otherwise>
> </xsl:choose>
> </xsl:for-each-group>
> </SN>
> </xsl:for-each-group>
> </body>
> </xsl:template>
Is there simultaneously an easy way to add in additional markup for the
individual lines inside of Q? i.e. either: <l>blah</l> or blah<lb/>?
so:
<Q value="foo"><l>blah blah blah</l>
<l>blah blah blah blah blah</l>
<l>blah blah blah blah blah</l><SSD value="foo"/>
<l>blah blah blah blah blah</l></Q>
<SSD value="blort"/>
> An XSLT 1.0 solution would be harder...
Yes, certainly. I'm assuming it isn't necessarily impossible? But
XSLT2 is fine with me ;-)
Offlist someone suggested the route of doing COCOA/OCP -> SGML with
omitted end-tags, create DTD specifying the relationships of
SN/Q/SSD, then sgml2xml conversion. This leads to any SSD at
the very end of a Q being included inside the Q since SSD has
to be allowed inside Q at some points.
Many Thanks,
-James
---
Dr James Cummings, Oxford Text Archive, James.Cummings@xxxxxxxxxxxxxx
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
| Current Thread |
|---|
|
| <- Previous | Index | Next -> |
|---|---|---|
| Re: [xsl] empty elements to filled , David Carlisle | Thread | Re: [xsl] empty elements to filled , Jeni Tennison |
| RE: [xsl] Node test--> text -->diff, Andreas L. Delmelle | Date | Re: [xsl] Node test--> text -->diff, Barry van Weldam |
| Month |