xsl-list
[Top] [All Lists]

Re: nesting non-nested nodes

2005-06-07 11:45:18
Andrew

I amended your xml for better readability and control of the result after 
transformation.

<?xml version="1.0" encoding="UTF-8?>
<Root>
        <head head-level="1">head title A1</head>
        <p>paragraph of A1</p>
        <head head-level="2">sub-head title A1.1</head>
        <p>paragraph of A1.1</p>
        <head head-level="2">sub-head title A1.2</head>
        <p>paragraph of A1.2</p>
        <head head-level="3">sub-sub-head title A1.2.1</head>
        <p>paragraph of A1.2.1</p>
        <head head-level="3">sub-sub-head title A1.2.2</head>
        <p>paragraph of A1.2.2</p>
        <head head-level="1">head title B1</head>
        <p>paragraph of B1</p>
</Root>

A similar question has been answered, please see '[xsl] flat XML to normal XML' 
in this list.

If you know the highest value for @head-level, the xslt is straight forward.
Note, that the <xsl:apply-template 
select="followin-sibling::head[1][(_at_)head-level='3']"/>
in the last template of the stylesheet is placed *after* the </level> 
because head elements with @head-level='3' must not be nested.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
<!-- Created:2005-06-07 Author:rudolf(_dot_)weinmann(_at_)assentis(_dot_)com 
http://www.assentis.com -->
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>

<xsl:template match="/">
        <NewDataSet>
                <!-- select all top level head elements -->
                <xsl:apply-templates select="Root/head[(_at_)head-level='1']"/>
        </NewDataSet>
</xsl:template>

<xsl:template match="head[(_at_)head-level='1']">
        <level>
                <title>
                        <xsl:value-of select="."/>
                </title>
                <xsl:copy-of select="following-sibling::p[1]"/> 
                <!-- select all adjaicent head elements with the next higher 
@head-level -->
                <xsl:apply-templates 
select="following-sibling::head[(_at_)head-level='2']"/>
        </level>
</xsl:template>

<xsl:template match="head[(_at_)head-level='2']">
        <level>
                <title>
                        <xsl:value-of select="."/>
                </title>
                <xsl:copy-of select="following-sibling::p[1]"/> 
                <!-- select the adjaicent head element, if it is the next 
higher @head-level -->
                <xsl:apply-templates 
select="following-sibling::head[1][(_at_)head-level='3']"/>
        </level>
</xsl:template>

<xsl:template match="head[(_at_)head-level='3']">
        <level>
                <title>
                        <xsl:value-of select="."/>
                </title>
                <xsl:copy-of select="following-sibling::p[1]"/> 
        </level>
        <!-- select the adjaicent head element, if it is the next higher 
@head-level -->
        <!-- this apply-templates is *after* </level>, because @head-level='3' 
elements must not be nested -->
        <xsl:apply-templates 
select="following-sibling::head[1][(_at_)head-level='3']"/>
</xsl:template>

</xsl:stylesheet>

And the result:
<?xml version='1.0' encoding='UTF-8' ?>
<NewDataSet>
  <level>
    <title>head title A1</title>
    <p>paragraph of A1</p>
    <level>
      <title>sub-head title A1.1</title>
      <p>paragraph of A1.1</p>
    </level>
    <level>
      <title>sub-head title A1.2</title>
      <p>paragraph of A1.2</p>
      <level>
        <title>sub-sub-head title A1.2.1</title>
        <p>paragraph of A1.2.1</p>
      </level>
      <level>
        <title>sub-sub-head title A1.2.2</title>
        <p>paragraph of A1.2.2</p>
      </level>
    </level>
  </level>
  <level>
    <title>head title B1</title>
    <p>paragraph of B1</p>
  </level>
</NewDataSet>

Hope this helps,
Rudolf

On Tue, 7 Jun 2005 10:48:49 -0400, you wrote:

Hello all,
I searched the archives for an answer to this, but I'm not sure how 
best to describe what I'm looking for. Sorry if this question has been 
asked previously. I'm trying to take non-nested nodes and get them 
nested. I'm using XSL version 1.0 and my processor is Libxslt.

SOURCE:

<head head-level="1">
      head title
</head>
<p>
      paragraph(s)
</p>
<head head-level="2">
      sub-head title
</head>
<p>
      paragraph(s)
</p>
<head head-level="2">
      sub-head title
</head>
<p>
      paragraph(s)
</p>
<head head-level="3">
      sub-sub-head title
</head>
<p>
      paragraph(s)
</p>
<head head-level="1">
      head title
</head>
<p>
      For simplicity, I've reduced any amount of content in between head's 
to a single p.
</p>


DESIRED RESULT:

<level>
      <title>
              head title
      </title>
      <p>
              paragraph(s)
      </p>
      <level>
              <title>
                      sub-head title
              </title>
              <p>
                      paragraph(s)
              </p>
      </level>
      <level>
              <title>
                      sub-head title
              </title>
              <p>
                      paragraph(s)
              </p>
              <level>
                      <title>
                              sub-sub-head title
                      </title>
                      <p>
                              paragraph(s)
                      </p>
              </level>
      </level>
</level>
<level>
      <title>
              head title
      </title>
      <p>
              For simplicity, I've reduced any amount of content in between 
head's 
to a single p.
      </p>
</level>


Thank you all. This list is such a valuable resource.

-Andrew


--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--






--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



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