Jump to content

Flat structure to nested xml..


webbenny

Recommended Posts

Hello! I've the following XML structure:

<root>  <title1>Titel 1</title1>  <para>Para 1</para>  <para>Para 2</para>  <para>Para 3</para>  <title2>Title 2</title2>  <para>Para 1</para>  <para>Para 2</para>  <title3>Title 3<3/title>  <para>Para 1</para>  <para>Para 2</para>  <title1>Title 1<1/title>  <para>Para 1</para>  <para>Para 2</para></root>

And the output should be:

<?xml version="1.0"?><root>  <layer0>	 <title>Titel 1</title>	 <para>Para 1</para>	 <para>Para 2</para>	 <para>Para 3</para>	 <layer1>		<title>Title 2</title>		<para>Para 1</para>		<para>Para 2</para>		<layer2>  		  <title>Title 3</title>		  <para>Para 1</para>		  <para>Para 2</para>		</layer2>	 </layer1>  </layer0>  <layer0>	 <title>Titel 1</title>	 <para>Para 1</para>	 <para>Para 2</para>	 <para>Para 3</para>  </layer0></root>

According to the example at http://www.dpawson.c....html#d5010e528 I've tried to do this.. But it seems to be impossible. My xslt output is a endless nested xml or a flat xml..Hast anybody done something similar? Best regards,webbenny

Edited by webbenny
Link to comment
Share on other sites

  • 2 months later...

The file can be converted to nested xml easier with non-xml based tools like perl and flex (in my opinion). However, if you must use XSLT here is what I use to convert a database file to html. Input File

<database><H1>Title 1</H1><para>Para 1</para><para>Para 2</para><para>Para 3</para><H2>Title 2</H2><para>Para 1</para><para>Para 2</para><H2>Title 2</H2><para>Para 1</para><para>Para 2</para><H3>Title 3</H3><para>Para 1</para><para>Para 2</para><H1>Title 1</H1><para>Para 1</para><para>Para 2</para><H3>Title 3</H3><para>Para 1</para><para>Para 2</para><H1>Title 1</H1><para>Para 1</para><para>Para 2</para><H3>Title 3</H3><para>Para 1</para><para>Para 2</para><H1>Title 1</H1><para>Para 1</para><para>Para 2</para><H2>Title 2</H2><para>Para 1</para><H3>Title 3</H3><para>Para 1</para><H2>Title 2</H2><para>Para 1</para></database>

Style Sheet

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"><xsl:output method="xml"/><xsl:template match="database">  <xsl:element name="html">   <xsl:for-each select="*">	<xsl:choose>	 <xsl:when test="name()='H1' ">	  <xsl:call-template name="H1"/>	 </xsl:when>	 <xsl:when test="name()='H2' ">	  <xsl:call-template name="H2"/>	 </xsl:when>	 <xsl:when test="name()='H3'">	  <xsl:call-template name="H3"/>	 </xsl:when>	 <xsl:otherwise>	  <xsl:call-template name="fallthru"/>	 </xsl:otherwise>	</xsl:choose>	<xsl:if test="position()=last()">	 <!-- close open levels -->	 <xsl:variable name="level">	  <xsl:call-template name="whatLevel">	   <xsl:with-param name="pointer" select="1"/>	  </xsl:call-template>	 </xsl:variable>	 <xsl:choose>	  <xsl:when test="$level = 'H1' ">	   <xsl:text disable-output-escaping="yes"></div></xsl:text>	  </xsl:when>	  <xsl:when test="$level = 'H2' ">	   <xsl:text disable-output-escaping="yes"></div></xsl:text>	   <xsl:text disable-output-escaping="yes"></div></xsl:text>	  </xsl:when>	  <xsl:when test="$level = 'H3' ">	   <xsl:text disable-output-escaping="yes"></div></xsl:text>	   <xsl:text disable-output-escaping="yes"></div></xsl:text>	   <xsl:text disable-output-escaping="yes"></div></xsl:text>	  </xsl:when>	  <xsl:otherwise>	   <xsl:text disable-output-escaping="yes"></div></xsl:text>	  </xsl:otherwise>	 </xsl:choose>	</xsl:if>   </xsl:for-each>  </xsl:element></xsl:template><xsl:template name="whatLevel">  <xsl:param name="pointer"/>  <xsl:if test="$pointer < 10">   <xsl:choose>	<xsl:when test="name(preceding-sibling::*[number($pointer)]) = ''"/>	<xsl:when test="name(preceding-sibling::*[number($pointer)]) = 'H1'">H1</xsl:when>	<xsl:when test="name(preceding-sibling::*[number($pointer)]) = 'H2'">H2</xsl:when>	<xsl:when test="name(preceding-sibling::*[number($pointer)]) = 'H3'">H3</xsl:when>	<xsl:otherwise>	 <xsl:call-template name="whatLevel">	  <xsl:with-param name="pointer">	   <xsl:value-of select="$pointer + 1"/>	  </xsl:with-param>	 </xsl:call-template>	</xsl:otherwise>   </xsl:choose>  </xsl:if></xsl:template><xsl:template match="H1" name="H1">  <xsl:variable name="level">   <xsl:call-template name="whatLevel">	<xsl:with-param name="pointer" select="1"/>   </xsl:call-template>  </xsl:variable>  <xsl:choose>   <xsl:when test="$level = 'H1' ">	<xsl:text disable-output-escaping="yes"></div></xsl:text>   </xsl:when>   <xsl:when test="$level = 'H2' ">	<xsl:text disable-output-escaping="yes"></div></xsl:text>	<xsl:text disable-output-escaping="yes"></div></xsl:text>   </xsl:when>   <xsl:when test="$level = 'H3' ">	<xsl:text disable-output-escaping="yes"></div></xsl:text>	<xsl:text disable-output-escaping="yes"></div></xsl:text>	<xsl:text disable-output-escaping="yes"></div></xsl:text>   </xsl:when>  </xsl:choose>  <xsl:text disable-output-escaping="yes"><div class="div1"></xsl:text>  <xsl:element name="th">   <xsl:apply-templates/>  </xsl:element></xsl:template><xsl:template match="H2" name="H2">  <!-- go backward through siblings to see what last title was -->  <xsl:variable name="level">   <xsl:call-template name="whatLevel">	<xsl:with-param name="pointer" select="1"/>   </xsl:call-template>  </xsl:variable>  <xsl:choose>   <xsl:when test="$level = 'H3'">	<xsl:text disable-output-escaping="yes"></div></xsl:text>	<xsl:text disable-output-escaping="yes"></div></xsl:text>   </xsl:when>   <xsl:when test="$level = 'H2'">	<xsl:text disable-output-escaping="yes"></div></xsl:text>   </xsl:when>  </xsl:choose>  <xsl:text disable-output-escaping="yes"><div class="div2"></xsl:text>  <xsl:element name="th">   <xsl:apply-templates/>  </xsl:element></xsl:template><xsl:template match="H3" name="H3">  <!-- go backward through siblings to see what last title was -->  <xsl:variable name="level">   <xsl:call-template name="whatLevel">	<xsl:with-param name="pointer" select="1"/>   </xsl:call-template>  </xsl:variable>  <xsl:choose>   <xsl:when test="$level = 'H3'">	<xsl:text disable-output-escaping="yes"></div></xsl:text>   </xsl:when>  </xsl:choose>  <xsl:if test="$level='H1'">   <xsl:text disable-output-escaping="yes"><div class="div2"></xsl:text>  </xsl:if>  <xsl:text disable-output-escaping="yes"><div class="div3"></xsl:text>  <xsl:element name="th">   <xsl:apply-templates/>  </xsl:element></xsl:template><xsl:template match="para">  <xsl:element name="p">   <xsl:apply-templates/>  </xsl:element></xsl:template><xsl:template match="*" name="fallthru">  <xsl:element name="{name()}">   <xsl:apply-templates/>  </xsl:element></xsl:template></xsl:stylesheet>

Output File

<?xml version="1.0" encoding="UTF-8"?><html><div class="div1">  <th>Title 1</th>  <para>Para 1</para>  <para>Para 2</para>  <para>Para 3</para>  <div class="div2">   <th>Title 2</th>   <para>Para 1</para>   <para>Para 2</para>  </div>  <div class="div2">   <th>Title 2</th>   <para>Para 1</para>   <para>Para 2</para>   <div class="div3">	<th>Title 3</th>	<para>Para 1</para>	<para>Para 2</para>   </div>  </div></div><div class="div1">  <th>Title 1</th>  <para>Para 1</para>  <para>Para 2</para>  <div class="div2">   <div class="div3">	<th>Title 3</th>	<para>Para 1</para>	<para>Para 2</para>   </div>  </div></div><div class="div1">  <th>Title 1</th>  <para>Para 1</para>  <para>Para 2</para>  <div class="div2">   <div class="div3">	<th>Title 3</th>	<para>Para 1</para>	<para>Para 2</para>   </div>  </div></div><div class="div1">  <th>Title 1</th>  <para>Para 1</para>  <para>Para 2</para>  <div class="div2">   <th>Title 2</th>   <para>Para 1</para>   <div class="div3">	<th>Title 3</th>	<para>Para 1</para>   </div>  </div>  <div class="div2">   <th>Title 2</th>   <para>Para 1</para>  </div></div></html>

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...