[xsl] Re: Adding structure to a docment based on attributes

Subject: [xsl] Re: Adding structure to a docment based on attributes
From: "Yang" <sfyang@xxxxxxxxxxxxx>
Date: Tue, 25 Sep 2001 14:09:26 +0800
Nichloas;

Following Wendell following suggestions
>Check out my contribution to the list at
>http://www.biglist.com/lists/xsl-list/archives/200012/msg00138.html and
>Jeni's improvements at
>http://www.biglist.com/lists/xsl-list/archives/200012/msg00175.html.

>This is basically a grouping problem. The secret is to think of the problem
>not as  working by "closing the logical structure at the right place", but
>by correctly identifying which nodes go into which logical structure, and
>pulling just those nodes in when you create it.

I submit two xslts for your reference  using Wendell and Jeni algorithms
which are written based on explicit element h1,h2,...h6.
It is a litter bit different from yours which hierarchical relations built
inside of **style** attributes.

Wendell, Jeni ;  your comment on my xslt are certainly appreciated.  Thanks.


***  xslt  based on Wendell's algorithm  **

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
    <xsl:output method="xml" indent="yes"/>
 <!--i.e., convert the attribute into element, it's value is related to p-->
<xsl:key name="Body" match="p[@style='Body']"
use="generate-id((..|preceding-sibling::p[@style='Heading1']|preceding-sibli
ng::p[@style='Heading2']
|preceding-sibling::p[@style='Heading3']|preceding-sibling::p[@style='Headin
g4']|preceding-sibling::p[@style='Heading5']
|preceding-sibling::p[@style='Heading6'])[last()])" />

<xsl:key name="h2" match="p[@style='Heading2']"
use="generate-id(preceding-sibling::p[@style='Heading1'][1])"/>
<xsl:key name="h3" match="p[@style='Heading3']"
use="generate-id(preceding-sibling::p[@style='Heading2'][1])"/>
<xsl:key name="h4" match="p[@style='Heading4']"
use="generate-id(preceding-sibling::p[@style='Heading3'][1])"/>
<xsl:key name="h5" match="p[@style='Heading5']"
use="generate-id(preceding-sibling::p[@style='Heading4'][1])"/>
<xsl:key name="h6" match="p[@style='Heading6']"
use="generate-id(preceding-sibling::p[@style='Heading5'][1])"/>

<!--   Wendell Piez algorithm -->
<xsl:template match="doc">
<main>
<xsl:apply-templates select="key('Body',generate-id())" mode="Body"/>
<xsl:apply-templates select="p[@style='Heading1']" mode="h1"/>
</main>
</xsl:template>

<xsl:template match="p" mode="h1">
<section level="1"><head><xsl:apply-templates/></head>
<xsl:apply-templates select="key('Body',generate-id())" mode="Body"/>
<xsl:apply-templates select="key('h2',generate-id())" mode="h2"/>
</section>
</xsl:template>

<xsl:template match="p" mode="h2">
<section level="2"><head><xsl:apply-templates/></head>
<xsl:apply-templates select="key('Body',generate-id())" mode="Body"/>
<xsl:apply-templates select="key('h3',generate-id())" mode="h3"/>
</section>
</xsl:template>

<xsl:template match="p" mode="h3">
<section level="3"><head><xsl:apply-templates/></head>
<xsl:apply-templates select="key('Body',generate-id())" mode="Body"/>
<xsl:apply-templates select="key('h4',generate-id())" mode="h4"/>
</section>
</xsl:template>

<xsl:template match="p" mode="h4">
<section level="4"><head><xsl:apply-templates/></head>
<xsl:apply-templates select="key('Body',generate-id())" mode="Body"/>
<xsl:apply-templates select="key('h5',generate-id())" mode="h5"/>
</section>
</xsl:template>

<xsl:template match="p" mode="h5">
<section level="5"><head><xsl:apply-templates/></head>
<xsl:apply-templates select="key('Body',generate-id())" mode="Body"/>
<xsl:apply-templates select="key('h6',generate-id())" mode="h6"/>
</section>
</xsl:template>

<xsl:template match="p" mode="h6">
<section level="6"><head><xsl:apply-templates/></head>
<xsl:apply-templates select="key('Body',generate-id())" mode="Body"/>
</section>
</xsl:template>

<xsl:template match="p" mode="Body">
<text><xsl:apply-templates/></text>
</xsl:template>
</xsl:stylesheet>

***  xslt 2 -  Using  Jeni's algorithm  ***
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
    <xsl:output method="xml" indent="yes"/>
 <!--i.e., convert the attribute into element, it's value is related to p-->

<xsl:key  name="next-headings" match="p[@style='Heading2']"
use="generate-id(preceding-sibling::p[@style='Heading1'
or @style='Heading2' or @style='Heading3' or @style='Heading4' or
@style='Heading5' or @style='Heading6'][1])"/>

<xsl:key  name="next-headings" match="p[@style='Heading3']"
use="generate-id(preceding-sibling::p[@style='Heading1'
or @style='Heading2' or @style='Heading3' or @style='Heading4' or
@style='Heading5' or @style='Heading6'][1])"/>

<xsl:key  name="next-headings" match="p[@style='Heading4']"
use="generate-id(preceding-sibling::p[@style='Heading1'
or @style='Heading2' or @style='Heading3' or @style='Heading4' or
@style='Heading5' or @style='Heading6'][1])"/>

<xsl:key  name="next-headings" match="p[@style='Heading5']"
use="generate-id(preceding-sibling::p[@style='Heading1'
or @style='Heading2' or @style='Heading3' or @style='Heading4' or
@style='Heading5' or @style='Heading6'][1])"/>

<xsl:key  name="next-headings" match="p[@style='Heading6']"
use="generate-id(preceding-sibling::p[@style='Heading1'
or @style='Heading2' or @style='Heading3' or @style='Heading4' or
@style='Heading5' or @style='Heading6'][1])"/>


<xsl:key  name="immediate-nodes" match="node()[not(@style='Heading1') and
not(@style='Heading2') and not(@style='Heading3')  and
not(@style='Heading4') and not(@style='Heading5') and
not(@style='Heading6')]"
use="generate-id(preceding-sibling::p[@style='Heading1' or @style='Heading2'
or @style='Heading3' or @style='Heading4' or @style='Heading5' or
@style='Heading6'][1])"/>

<!-- Jeni's  Algorithm  -->
<xsl:template match="doc">
<main>
<xsl:apply-templates select="p[@style='Heading1']" />
</main>
</xsl:template>

<xsl:template match="p" >
<xsl:variable name="level"
select="substring-after(@*[name()='style'],'ing')"/>

<section level="{$level}">
<head><xsl:apply-templates/></head>
<xsl:apply-templates select="key('immediate-nodes',generate-id())"
mode="Body"/>
<xsl:apply-templates select="key('next-headings',generate-id())" />
</section>
</xsl:template>

<xsl:template match="node()">
<xsl:copy-of select="."/>
</xsl:template>

<xsl:template match="p" mode="Body">
<text><xsl:apply-templates/></text>
</xsl:template>
</xsl:stylesheet>

**   xml  ***
<doc>
<p style="Heading1">Top Level Heading</p>
<p style="Body">Some text at this level</p>
<p style="Heading2">Sub Heading 1</p>
<p style="Body">Some text here</p>
<p style="Heading2">Sub heading 2</p>
<p style="Body">Some text here</p>
<p style="Heading3">Sub Heading 3</p>
<p style="Body">Body 3 text</p>
<p style="Heading4">Sub Heading 4</p>
<p style="Body">Body 4 text</p>
<p style="Heading1">Another Heading</p>
<p style="Body">Some more text here</p>
</doc>


Sun-fu Yang

sfyang@xxxxxxxxxxxxx


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


Current Thread