xsl-list
[Top] [All Lists]

Re: How to implement Divide and Conquer Algo on this template !! Getting Callstack overflow error

2003-09-19 15:58:54
Hi,
As you said I made a key to get the TableName like this.

xsl:key name="uniqueTableNames" match="/Root/FNode/SNode/Table/@TableName" 
use="@NAME"/>


Then i m using it to get the values like this

<xsl:for-each   select="ROOT/FNODE/SNODE/TABLE/@TableName[generate-id(.) = 
generate-id(key('uniqueTableNames', @TableName)[1])]">
        <Column Name="@TableName"/>
   </xsl:for-each>

I am stuck here. There is something wrong in the XPATH as it is not going 
inside the for-each statement. Can someone please correct this.

Now to get the desired output i have thought of the following logic.

1) Get each unique table name(In the above for loop)
2) Call-template and pass this table name as a parameter
3) For this table name create key dynamically to get the Column names 
something like this.

<xsl:key name="columnNames" 
match="/Root/FNode/SNODE/TABLE[normalize-space(@NAME)=$paramTableName]/Row/Col
umn/@Name" use=(_at_)Name/>

Am i right ?

4) Then i will output each column name by running a for loop.
5) The process will repeat for each unique table name.

Here is my xsl file:
-------------------

<?xml version="1.0"?>

<xsl:stylesheet
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
        version="1.0">
<xsl:output method="xml" indent="yes"/>

<xsl:key name="attNamesFnode"
match="/Root/FNode/@*" use="name()"/>

<xsl:key name="attNamesSnode"
match="/Root/FNode/SNode/@*" use="name()"/>

<xsl:key name="uniqueTableNames" match="/Root/FNode/SNode/Table/@TableName" 
use="@NAME"/>
<xsl:template match="/">
<!-- Outputting fixed table -->
<Root>
 <FixedTables>
   <Table Name="FNODE">
      <Column PrimaryKey="FNODEID"/>
        <xsl:for-each   select="Root/FNode/@*[generate-id() = 
generate-id(key('attNamesFnode', name())[1])]">
                <Column Name="{name()}"/>
        </xsl:for-each>
   </Table>

   <Table Name="SNODE">
        <Column ForeignKey="FNODEID"/>
        <Column PrimaryKey="SNODEID"/>
        <xsl:for-each   select="ROOT/FNODE/SNODE/@*[generate-id() = 
generate-id(key('attNamesSnode', name())[1])]">
                        <Column Name="{name()}"/>
        </xsl:for-each>
   </Table>
  </FixedTables>
  </Root>

  <!-- Outputting Varying Number of tables with varying number of columns -->
   <xsl:for-each        
select="ROOT/FNODE/SNODE/TABLE/@TableName[generate-id(.) = 
generate-id(key('uniqueTableNames', @TableName)[1])]">
        <Column Name="@TableName"/>
   </xsl:for-each>
                
</xsl:template>
</xsl:stylesheet>
------------------------------------------------------------------
I have pasted the desired output in my previous email.

If i am able to write this then it will be efficient solution. But I am stuck 
at few places as I said above.

I am trying to look into archives to get good idea of how to write complex 
Xpath expression.

If someone can show me how to get the desired output, it will be really 
helpful and highly appreciated.

I am also trying to get the efficent solution. I have got the solution but it 
was inefficient and didn't worked well when I had huge input file.

Eagerly waiting for reply.

Regards,
Dipesh





Date: Fri, 19 Sep 2003 20:22:40 +0200
From: "Dimitre Novatchev" <dnovatchev(_at_)yahoo(_dot_)com>
Subject: [xsl] Re: How to implement Divide and Conquer Algo on this template 
!! Getting Callstack overflow error

Read more about the application of the Muenchian method -- there are many
posts in this list solving exactly your problem.

Briefly put, use two keys -- one matching "Table/@TableName" elements and
the other matching Column/@Name the parent of which has a "Table"
grandparent with specific value of the "TableName" attribute.

Hint:

The use attribute of the last xsl:key will be:

concat(../../../@TableName, '|', .)


=====
Cheers,

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


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