Re: [xsl] XSLT 1: From flat XML to tree hierarchy XML. Can't seem to find the right way to do it.

Subject: Re: [xsl] XSLT 1: From flat XML to tree hierarchy XML. Can't seem to find the right way to do it.
From: Abel Braaksma Online <abel.online@xxxxxxxxx>
Date: Thu, 25 May 2006 14:35:18 +0200
Hello all,

Just an update: I see I've made a mistake in the cut 'n' pasting below. Both twz-namespaces declarations should point to the same namespace, of course. In reality, they do indeed. The output does not have any namespace.

Input xml has this: xmlns="http://something.com";
Xslt has this: xmlns:twz="http://www.nuntia.com/tablewiz1.0";
Should both point to "http://www.nuntia.com/tablewiz1.0"; (not a real location of course).


Cheers,
Abel

Abel Braaksma Online wrote:

Dear XSLT Experts,

I am having some trouble with tackling a specific problem using XSLT 1.0. No extensions possible: it is used in client side browsers (IE, Opera, Safari and Firefox). So, it is not possible to use xpaths with default namespace , because IE can't correctly deal with it (hence all the xpaths with ns prefixes).

The data is arbitrary, but comes from a live system, so it should be correct. The "expected output" is done by hand. The provided XSLT is not really creating that, in fact, it outputs some tree with all the same names everywhere. I clearly made mistakes, but after trying for a few days all kinds of xpaths etc., I gave up.

RULES:
A. If items have no child categories at all, create a <item> node without children, using the text of the input node <tableName> for the @text attribute, inside the current <item> that has @text = current(@category-name.
B. If items have child categories, create an <item> node with children that consist of A, B
C. If items have child categories, but B is done, do A.
==> overall result: a treeview structure reflecting something like Windows Directory tree with files on the bottom, after all maps.


EXPECTED OUTPUT:
<tree id="0">
   <item text="Root" id="Root" open="1" call="1">
       <item text="Printers" id="Printers" >
           <item text="List of printers locally" id="12" />
           <item text="External Oce printers" id="13" />
       </item>
       <item text="General" id="General">
           <item text="Personnel" id="Personnel">
               <item text="Signatures" id="Signatures">
                   <item text="List of signatures" id="20" />
               </item>
               <item text="Child-item of Personnel" id="9" />
               <item text="Other personnel member" id="10" />
               <item text="Final personnel member" id="11" />
           </item>
           <item text="General usage table" id="15" />
           <item text="Genes of mambutam" id="18" />
           <item text="Generosity clears" id="19" />
           <item text="General cooking table" id="16" />
           <item text="General General" id="17" />
       </item>
       <item text="Some tableaname at rootlevel" id="5" />
       <item text="Very rooty table" id="14" />
       <item text="Rootlevel table 3" id="22" />
       <item text="Rootlevel table 3" id="24" />
       <item text="Rootlevel table 3" id="25" />
       <item text="Rootlevel table 3" id="26" />
    </item>
</tree>

XML INPUT for use with XSLT file below:
<message xmlns="http://something.com"; >
<response>
<responseMessage response-status="success">Table names retrieved successfully!</responseMessage>
<userData request="getTableNames" timestamp="1148407486082" client-version="0.9"/>
<tableName id="5" category-name="Root">testcsv3</tableName>
<tableName id="7" category-name="Root">[New table 2]</tableName>
<tableName id="8" category-name="Root">ee</tableName>
<tableName id="9" category-name="Personnel" category-parent-name="General">Child of Personnel</tableName>
<tableName id="10" category-name="Personnel" category-parent-name="General">Other personnel member</tableName>
<tableName id="11" category-name="Personnel" category-parent-name="General">Final personnel member</tableName>
<tableName id="12" category-name="Printers" category-parent-name="Root">List of printers locally</tableName>
<tableName id="13" category-name="Printers" category-parent-name="Root">External Oce printers</tableName>
<tableName id="14" category-name="Root">Very rooty table</tableName>
<tableName id="15" category-name="General" category-parent-name="Root">General usage table</tableName>
<tableName id="16" category-name="General" category-parent-name="Root">General cooking table</tableName>
<tableName id="17" category-name="General" category-parent-name="Root">General General</tableName>
<tableName id="18" category-name="General" category-parent-name="Root">Genes of mambutam</tableName>
<tableName id="19" category-name="General" category-parent-name="Root">Generosity clears</tableName>
<tableName id="20" category-name="Signatures" category-parent-name="Personnel">List of signatures</tableName>
</response>
</message>




XSLT for transforming above snippet:

<xsl:stylesheet version="1.0"    exclude-result-prefixes="twz xsl"
   xmlns="http://www.w3.org/1999/xhtml";
   xmlns:twz="http://www.nuntia.com/tablewiz1.0";
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<tree id="0">
<xsl:apply-templates select="//twz:tableName[@category-name = 'Root']" />
</tree>
</xsl:template>
<xsl:template match="twz:tableName">
<xsl:variable name="parent-category" select="@category-parent-name" />
<xsl:variable name="category" select="@category-name" />
<xsl:choose>
<xsl:when test="../twz:tableName[@category-parent-name = $category]">
<item text="{@category-name}" id="{@id or @category-name}" open="1" call="1"> <xsl:apply-templates select="../twz:tableName[@category-parent-name = $category]" />
</item>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="text()" /> </xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="twz:tableName/text()">
<item text="TEXT {.}" id="{.}" call="1" />
</xsl:template>


</xsl:stylesheet>

Current Thread