xsl-list
[Top] [All Lists]

Re: XML to XML

2003-03-26 15:56:48
Hi Jim,

Try something like this:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
 xmlns:vendor="http://icl.com/saxon";
 xmlns:nums="f:nums" exclude-result-prefixes="nums vendor">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <nums:nums>
   <One/>
   <Two/>
   <Three/>
 </nums:nums>

   <xsl:template match="/">
     <xsl:variable name="vPass1">
       <xsl:apply-templates/>
     </xsl:variable>

     <Categories>
       <xsl:apply-templates mode="pass2"
       select="vendor:node-set($vPass1)/*
                            [string-length(@Code) = 1]"/>
     </Categories>
   </xsl:template>

   <xsl:template match="Categories">
    <xsl:apply-templates select="Category">
      <xsl:sort select="Code"/>
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="Category">
    <xsl:variable name="vNums" select="document('')/*/nums:*"/>

    <xsl:element
name="Level{name($vNums/*[string-length(current()/Code)])}Category">
      <xsl:attribute name="Code">
        <xsl:value-of select="Code"/>
      </xsl:attribute>
      <xsl:attribute name="Description">
        <xsl:value-of select="Description"/>
      </xsl:attribute>
    </xsl:element>
  </xsl:template>

  <xsl:template match="*" mode="pass2">
    <xsl:variable name="vcurLevel" select="string-length(@Code)"/>

    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates mode="pass2"
       select="following-sibling::*[string-length(@Code)
                                   =
                                    $vcurLevel + 1
                                  and
                                    generate-id(current())
                                   =
                                    generate-id(preceding-sibling::*
                                                  [string-length(@Code)
                                                  =
                                                   $vcurLevel
                                                   ][1]
                                                )
                                    ]"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

When applied to your source.xml:

<Categories>
  <Category>
    <Code>A</Code>
    <Description>Airplanes</Description>
  </Category>
  <Category>
    <Code>AA</Code>
    <Description>Airplanes (ARF)</Description>
  </Category>
  <Category>
    <Code>AAE</Code>
    <Description>Airplanes (ARF), Electric</Description>
  </Category>
  <Category>
    <Code>AAG</Code>
    <Description>Airplanes (ARF), Giant</Description>
  </Category>
  <Category>
    <Code>AAP</Code>
    <Description>Airplanes (ARF), Sailplane</Description>
  </Category>
  <Category>
    <Code>B</Code>
    <Description>Boats</Description>
  </Category>
  <Category>
    <Code>BA</Code>
    <Description>Boats (ARF)</Description>
  </Category>
  <Category>
    <Code>BAE</Code>
    <Description>Boats (ARF), Electric</Description>
  </Category>
</Categories>

the above transformation produces the wanted result:

<Categories>
   <LevelOneCategory Code="A" Description="Airplanes">
      <LevelTwoCategory Code="AA" Description="Airplanes (ARF)">
         <LevelThreeCategory Code="AAE" Description="Airplanes (ARF),
Electric"/>
         <LevelThreeCategory Code="AAG" Description="Airplanes (ARF),
Giant"/>
         <LevelThreeCategory Code="AAP" Description="Airplanes (ARF),
Sailplane"/>
      </LevelTwoCategory>
   </LevelOneCategory>
   <LevelOneCategory Code="B" Description="Boats">
      <LevelTwoCategory Code="BA" Description="Boats (ARF)">
         <LevelThreeCategory Code="BAE" Description="Boats (ARF),
Electric"/>
      </LevelTwoCategory>
   </LevelOneCategory>
</Categories>


=====
Cheers,

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

"Jim Han" <jhan(_at_)horizonhobby(_dot_)com> wrote in message
news:DFA25A23407A8143B9070FD0F3AFF51C0291DCCB(_at_)rusty(_dot_)horizonhobby(_dot_)com(_dot_)(_dot_)(_dot_)
I need some help in writing xsl to transform XML to XML.
I am getting lost in concepts of having multiple templates

Original:
<Categories>
<Category>
<Code>A</Code>
<Description>Airplanes</Description>
</Category>
<Category>
<Code>AA</Code>
<Description>Airplanes (ARF)</Description>
</Category>
<Category>
<Code>AAE</Code>
<Description>Airplanes (ARF), Electric</Description>
</Category>
<Category>
<Code>AAG</Code>
<Description>Airplanes (ARF), Giant</Description>
</Category>
<Category>
<Code>AAP</Code>
<Description>Airplanes (ARF), Sailplane</Description>
</Category>
<Category>
<Code>B</Code>
<Description>Boats</Description>
</Category>
<Category>
<Code>BA</Code>
<Description>Boats (ARF)</Description>
</Category>
<Category>
<Code>BAE</Code>
<Description>Boats (ARF), Electric</Description>
</Category>
<Categories>


Final Result - where one letter, two letter, and three letter categories
are
nested.


<Categories>
<LevelOneCategory Code="A" Description="Airplanes">
<LevelTwoCategory Code="AA" Description="Airplanes (ARF)">
<LevelThreeCategory  Code="AAE"
Description="Airplanes (ARF), Electric"/>
<LevelThreeCategory  Code="AAG"
Description="Airplanes (ARF), Giant"/>
<LevelThreeCategory  Code="AAP"
Description="Airplanes (ARF), Sailplane"/>
</LevelTwoCategory>
      </LevelOneCategory>
<LevelOneCategory Code="B" Description="Boats">
<LevelTwoCategory Code="BA" Description="Boats (ARF)">
<LevelThreeCategory  Code="BAE" Description="Boats
(ARF), Electric"/>
</LevelTwoCategory>
      </LevelOneCategory>
<Categories>

Thank you!


Jim Han





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






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



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