[xsl] Re: restructuring element hierarchy using xslt- complications

Subject: [xsl] Re: restructuring element hierarchy using xslt- complications
From: "Dimitre Novatchev" <dnovatchev@xxxxxxxxx>
Date: Tue, 30 Sep 2003 14:31:00 +0200
"james walker" <jameswalkerandy@xxxxxxxxxxx> wrote in message
news:Law9-F113w2eA6oGuSU0004defb@xxxxxxxxxxxxxx
> When taking this further i have realised that maybe the problem is more
> complicate dthan i first thought, see u what u think below::
> (apologies for the layout, done in hotmail so may look a little shabby)
> the xml file looks like this:
>
> <t>
> <het position="1">
> <entrydata columnnumber="0">
> <text>some more text here</text></entrydata>
> </het>
> <het position="1.1">
> <entrydata columnnumber="1">
> <text>some more text here</text></entrydata>
> </het>
> <het position="1.1.1">
> <entrydata columnnumber="2">
> <text>text here</text></entrydata>
> <entrydata columnnumber="3">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="4">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="5">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="6">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="7">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="8">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="9">
> <text></text></entrydata>
> </het>
> <het position="1.1.2">
> <entrydata columnnumber="2">
> <text>text here</text></entrydata>
> <entrydata columnnumber="3">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="4">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="5">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="6">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="7">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="8">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="9">
> <text></text></entrydata>
> </het>
> <het position="2">
> <entrydata columnnumber="0">
> <text>some more text here</text></entrydata>
> </het>
> <het position="2.1">
> <entrydata columnnumber="1">
> <text>some more text here</text></entrydata>
> </het>
> <het position="2.1.1">
> <entrydata columnnumber="2">
> <text>text here</text></entrydata>
> <entrydata columnnumber="3">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="4">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="5">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="6">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="7">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="8">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="9">
> <text></text></entrydata>
> </het>
> </t>
>
> and i was trying to recode it to nest:
>
>
> <t>
> <het position="1">
> <entrydata columnnumber="0">
> <text>some more text here</text></entrydata>
> <het position="1.1">
> <entrydata columnnumber="1">
> <text>some more text here</text></entrydata>
> <het position="1.1.1">
> <entrydata columnnumber="2">
> <text>text here</text></entrydata>
> <entrydata columnnumber="3">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="4">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="5">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="6">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="7">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="8">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="9">
> <text></text></entrydata>
> </het>
> <het position="1.1.2">
> <entrydata columnnumber="2">
> <text>text here</text></entrydata>
> <entrydata columnnumber="3">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="4">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="5">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="6">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="7">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="8">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="9">
> <text></text></entrydata>
> </het>
> </het>
> </het>
> <het position="2">
> <entrydata columnnumber="0">
> <text>some more text here</text></entrydata>
> <het position="2.1">
> <entrydata columnnumber="1">
> <text>some more text here</text></entrydata>
> <het position="2.1.1">
> <entrydata columnnumber="2">
> <text>text here</text></entrydata>
> <entrydata columnnumber="3">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="4">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="5">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="6">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="7">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="8">
> <text>more text here</text></entrydata>
> <entrydata columnnumber="9">
> <text></text></entrydata>
> </het>
> </het>
> </het>
> </t>
> but still hvaing a meard with it, any suggestions would be appreciated.

Yes, what is needed is within the template matching "het" to copy all the
contents of the current node. This is done by:

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


>
> also, at the same time i thought that renaming different levelled hets
would
> be a good idea- any het with 1-9 = res, 1.1-1.9 = rol, 1.1.1-1.1.9 = prod,
> so it would look like
> <t>
> <res>
> <rol>
> <prod>
> </prod>
> <prod>
> </prod>
> </rol>
> <rol>
> <prod>
> </prod>
> </rol>
> </res>
> </t>
> would i have to create new elements or is there a function to change
element
> names??

No, better pass as parameter to the template matching "het" the element name
to be used. I would put all such element names in a node-set and pass this
as a parameter. The template will use the contents of the first element in
this node-set, then when it applies templates to the "het" elements
belonging to the next lower level, it will pass to them as parameter the
same node-set, but starting from its second element.

In this way one can keep the xslt transformation generic and specify the
element names for each level of the hierarchy (the depth is unlimited) in an
external param/data-structure.


I define a namespace:

 xmlns:myLevels="my:Levels"

and the node-set with the element names:

 <myLevels:myLevels>
   <level>res</level>
   <level>rol</level>
   <level>prod</level>
 </myLevels:myLevels>


Then the complete transformation, which implements your last two
requirements is:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
 xmlns:myLevels="my:Levels"
 exclude-result-prefixes="myLevels">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <myLevels:myLevels>
   <level>res</level>
   <level>rol</level>
   <level>prod</level>
 </myLevels:myLevels>

 <xsl:variable name="Digits" select="1234567890"/>

 <xsl:template match="/*">
  <t>
   <xsl:apply-templates select="het[not(contains(@position, '.'))]">
    <xsl:with-param name="plevelNames"
                    select="document('')/*/myLevels:*/*"/>
    </xsl:apply-templates>
   </t>
 </xsl:template>

  <xsl:template match="het">
    <xsl:param name="plevelNames" select="/.."/>
    <xsl:element name="{$plevelNames[1]}">
      <xsl:copy-of select="@*"/>
      <xsl:copy-of select="node()"/>
      <xsl:apply-templates
       select="../het[starts-with(@position, current()/@position)
                     and
                      string-length(translate(@position,
                                              $Digits,
                                              ''
                                              )
                                   )
                      =
                       1 + string-length(translate(current()/@position,
                                                   $Digits,
                                                  ''
                                                  )
                                         )
                     ]">
          <xsl:with-param name="plevelNames"
               select="$plevelNames[position() > 1]"/>
       </xsl:apply-templates>
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>


When this transformation is applied on your source.xml:

<t>
  <het position="1">
    <entrydata columnnumber="0">
      <text>some more text here</text>
    </entrydata>
  </het>
  <het position="1.1">
    <entrydata columnnumber="1">
      <text>some more text here</text>
    </entrydata>
  </het>
  <het position="1.1.1">
    <entrydata columnnumber="2">
      <text>text here</text>
    </entrydata>
    <entrydata columnnumber="3">
      <text>more text here</text>
    </entrydata>
    <entrydata columnnumber="4">
      <text>more text here</text>
    </entrydata>
    <entrydata columnnumber="5">
      <text>more text here</text>
    </entrydata>
    <entrydata columnnumber="6">
      <text>more text here</text>
    </entrydata>
    <entrydata columnnumber="7">
      <text>more text here</text>
    </entrydata>
    <entrydata columnnumber="8">
      <text>more text here</text>
    </entrydata>
    <entrydata columnnumber="9">
      <text></text>
    </entrydata>
  </het>
  <het position="1.1.2">
    <entrydata columnnumber="2">
      <text>text here</text>
    </entrydata>
    <entrydata columnnumber="3">
      <text>more text here</text>
    </entrydata>
    <entrydata columnnumber="4">
      <text>more text here</text>
    </entrydata>
    <entrydata columnnumber="5">
      <text>more text here</text>
    </entrydata>
    <entrydata columnnumber="6">
      <text>more text here</text>
    </entrydata>
    <entrydata columnnumber="7">
      <text>more text here</text>
    </entrydata>
    <entrydata columnnumber="8">
      <text>more text here</text>
    </entrydata>
    <entrydata columnnumber="9">
      <text></text>
    </entrydata>
  </het>
  <het position="2">
    <entrydata columnnumber="0">
      <text>some more text here</text>
    </entrydata>
  </het>
  <het position="2.1">
    <entrydata columnnumber="1">
      <text>some more text here</text>
    </entrydata>
  </het>
  <het position="2.1.1">
    <entrydata columnnumber="2">
      <text>text here</text>
    </entrydata>
    <entrydata columnnumber="3">
      <text>more text here</text>
    </entrydata>
    <entrydata columnnumber="4">
      <text>more text here</text>
    </entrydata>
    <entrydata columnnumber="5">
      <text>more text here</text>
    </entrydata>
    <entrydata columnnumber="6">
      <text>more text here</text>
    </entrydata>
    <entrydata columnnumber="7">
      <text>more text here</text>
    </entrydata>
    <entrydata columnnumber="8">
      <text>more text here</text>
    </entrydata>
    <entrydata columnnumber="9">
      <text></text>
    </entrydata>
  </het>
</t>

the wanted result is produced:

<t>
   <res position="1">
      <entrydata columnnumber="0">
         <text>some more text here</text>
      </entrydata>
      <rol position="1.1">
         <entrydata columnnumber="1">
            <text>some more text here</text>
         </entrydata>
         <prod position="1.1.1">
            <entrydata columnnumber="2">
               <text>text here</text>
            </entrydata>
            <entrydata columnnumber="3">
               <text>more text here</text>
            </entrydata>
            <entrydata columnnumber="4">
               <text>more text here</text>
            </entrydata>
            <entrydata columnnumber="5">
               <text>more text here</text>
            </entrydata>
            <entrydata columnnumber="6">
               <text>more text here</text>
            </entrydata>
            <entrydata columnnumber="7">
               <text>more text here</text>
            </entrydata>
            <entrydata columnnumber="8">
               <text>more text here</text>
            </entrydata>
            <entrydata columnnumber="9">
               <text/>
            </entrydata>
         </prod>
         <prod position="1.1.2">
            <entrydata columnnumber="2">
               <text>text here</text>
            </entrydata>
            <entrydata columnnumber="3">
               <text>more text here</text>
            </entrydata>
            <entrydata columnnumber="4">
               <text>more text here</text>
            </entrydata>
            <entrydata columnnumber="5">
               <text>more text here</text>
            </entrydata>
            <entrydata columnnumber="6">
               <text>more text here</text>
            </entrydata>
            <entrydata columnnumber="7">
               <text>more text here</text>
            </entrydata>
            <entrydata columnnumber="8">
               <text>more text here</text>
            </entrydata>
            <entrydata columnnumber="9">
               <text/>
            </entrydata>
         </prod>
      </rol>
   </res>
   <res position="2">
      <entrydata columnnumber="0">
         <text>some more text here</text>
      </entrydata>
      <rol position="2.1">
         <entrydata columnnumber="1">
            <text>some more text here</text>
         </entrydata>
         <prod position="2.1.1">
            <entrydata columnnumber="2">
               <text>text here</text>
            </entrydata>
            <entrydata columnnumber="3">
               <text>more text here</text>
            </entrydata>
            <entrydata columnnumber="4">
               <text>more text here</text>
            </entrydata>
            <entrydata columnnumber="5">
               <text>more text here</text>
            </entrydata>
            <entrydata columnnumber="6">
               <text>more text here</text>
            </entrydata>
            <entrydata columnnumber="7">
               <text>more text here</text>
            </entrydata>
            <entrydata columnnumber="8">
               <text>more text here</text>
            </entrydata>
            <entrydata columnnumber="9">
               <text/>
            </entrydata>
         </prod>
      </rol>
   </res>
</t>


=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL





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


Current Thread