Subject: [xsl] Re: How to implement Divide and Conquer Algo on this template !! Getting Callstack overflow error From: "Dimitre Novatchev" <dnovatchev@xxxxxxxxx> Date: Sat, 20 Sep 2003 09:36:55 +0200 |
Here we go: This transformation: <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:key name="ktableNames" match="Table" use="@TableName"/> <xsl:key name="ktableColNames" match="Column" use="concat(../../@TableName, '|', @Name )"/> <xsl:template match="/"> <Root> <Tables> <xsl:for-each select="/*/*/*/Table[generate-id() = generate-id(key('ktableNames', @TableName )[1] ) ]"> <Table Name="{@TableName}"> <xsl:for-each select="key('ktableNames', @TableName)/Row/Column [generate-id() = generate-id(key('ktableColNames', concat(../../@TableName, '|', @Name ) )[1] ) ]"> <Column Name="{@Name}"/> </xsl:for-each> </Table> </xsl:for-each> </Tables> </Root> </xsl:template> </xsl:stylesheet> when applied on your source.xml: <Root> <FNode> <SNode> <Table TableName="fName"> <Row> <Column Name="ColName1"/> <Column Name="ColName2"/> </Row> <Row> <Column Name="ColName1"/> <Column Name="ColName3"/> <Column Name="ColName4"/> </Row> </Table> <Table TableName="SecondTname"> <Row> <Column Name="ColName1"/> <Column Name="ColName2"/> <Column Name="ColName3"/> <Column Name="ColName4"/> </Row> <Row> <Column Name="ColName1"/> <Column Name="ColName5"/> <Column Name="ColName6"/> </Row> </Table> </SNode> <SNode> <Table TableName="fName"> <Row> <Column Name="ColName1"/> <Column Name="ColName2"/> </Row> <Row> <Column Name="ColName1"/> <Column Name="ColName5"/> <Column Name="ColName6"/> </Row> </Table> <Table TableName="SecondTname"> <Row> <Column Name="ColName2"/> <Column Name="ColName3"/> </Row> <Row> <Column Name="ColName7"/> <Column Name="ColName8"/> </Row> </Table> <Table TableName="ThirdTname"> <Row> <Column Name="ColName1"/> <Column Name="ColName2"/> </Row> </Table> </SNode> </FNode> </Root> produces the wanted result: <Root> <Tables> <Table Name="fName"> <Column Name="ColName1"/> <Column Name="ColName2"/> <Column Name="ColName3"/> <Column Name="ColName4"/> <Column Name="ColName5"/> <Column Name="ColName6"/> </Table> <Table Name="SecondTname"> <Column Name="ColName1"/> <Column Name="ColName2"/> <Column Name="ColName3"/> <Column Name="ColName4"/> <Column Name="ColName5"/> <Column Name="ColName6"/> <Column Name="ColName7"/> <Column Name="ColName8"/> </Table> <Table Name="ThirdTname"> <Column Name="ColName1"/> <Column Name="ColName2"/> </Table> </Tables> </Root> ===== Cheers, Dimitre Novatchev. http://fxsl.sourceforge.net/ -- the home of FXSL "Dipesh Khakhkhar" <dkhakhkh@xxxxxxxxxxxxxxx> wrote in message news:3F6F084F@xxxxxxxxxxxxx > 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/C ol > umn/@Name" use=@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@xxxxxxxxx> > 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 > > XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] Re: How to implement Divide a, Dipesh Khakhkhar | Thread | [xsl] Can't filter the data correct, alexscott |
[xsl] Relation between Memory /Tim, Dipesh Khakhkhar | Date | [xsl] Re: Relation between Memory , Dimitre Novatchev |
Month |