This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RE: creating list from structured paragraphs


Jenni, first, thanks...

> If your para elements hold a mixture of text nodes and para-1 elements
> intermingled (i.e. several lists, or text appearing before and after
> lists), then you need to use a grouping method. I favour a
> step-by-step method in these cases -- apply templates to the first
> node of the para element:

Yes, these 'para-n' elements stem from SGML ranking with these declarations:

<!ELEMENT PARA 0          - o (%inline; | PARA1)*>
<!ELEMENT PARA 1          - o (%inline; | PARA2)*>
<!ELEMENT PARA 2          - o (%inline; | PARA3)*>
<!ELEMENT PARA 3          - o (%inline; | PARA4)*>
<!ELEMENT PARA 4          - o (%inline; | PARA5)*>
<!ELEMENT PARA 5          - o (%inline;)*>
<!ELEMENT PARA            - o (%inline; | PARA0 | PARA1)*>

I'm using 'sx' to convert to XML which is then styled by XSLT to produce a
rather different XML. I'll implement your solution and return the results.

thanks again,

David


>
> <xsl:template match="para">
>   <para>
>     <xsl:apply-template select="(text() | *)[1]" mode="para" />
>   </para>
> </xsl:template>
>
> Then, for text nodes, just give the value of the text node and move on
> to the next node:
>
> <xsl:template match="text()" mode="para">
>   <xsl:value-of select="." />
>   <xsl:apply-templates select="following-sibling::*[1]" mode="para" />
> </xsl:template>
>
> For para-1 elements, if you've applied templates in para mode then you
> need to create a list, then step through the following para-1 elements
> to create the content of the list. After creating the list, apply
> templates to the next text node (or element) that isn't a para-1
> element:
>
> <xsl:template match="para-1" mode="para">
>   <list>
>     <xsl:apply-templates select="." mode="list-item" />
>   </list>
>   <xsl:apply-templates mode="para"
>     select="following-sibling::node()[not(self::para-1)][1]" />
> </xsl:template>
>
> <xsl:template match="para-1" mode="list-item">
>   <list-item>
>     <xsl:apply-templates />
>   </list-item>
>   <xsl:apply-templates mode="list-item"
>     select="following-sibling::node()[1][self::para-1]" />
> </xsl:template>
>
> ---
>
> The XSLT 2.0 method is to group adjacent sets of nodes, and have the
> grouping value oscillate between true and false -- true when the node
> is a para-1 element and false when it isn't:
>
> <xsl:template match="para">
>   <xsl:for-each-group select="node()"
>                       group-adjacent="self::para-1">
>     <xsl:choose>
>       <xsl:when test="self::para-1">
>         <list>
>           <xsl:apply-templates select="current-group()" />
>         </list>
>       </xsl:when>
>       <xsl:otherwise>
>         <xsl:apply-templates select="current-group()" />
>       </xsl:otherwise>
>     </xsl:choose>
>   </xsl:for-each-group>
> </xsl:template>
>
> <xsl:template match="para-1">
>   <list-item>
>     <xsl:apply-templates />
>   </list-item>
> </xsl:template>
>
> I suspect that this is a pattern we'll see quite a lot of in XSLT 2.0.
> It's a little non-obvious at first (though no more non-obvious than
> the grouping hoops that we have to jump through in XSLT 1.0).
>
> Cheers,
>
> Jeni
>
> ---
> Jeni Tennison
> http://www.jenitennison.com/
>


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]