Subject: Re: [xsl] Recursion From: "Imsieke, Gerrit, le-tex" <gerrit.imsieke@xxxxxxxxx> Date: Mon, 28 May 2012 13:38:03 +0200 |
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0" exclude-result-prefixes="xs" >
<!-- If there is other content than xml1 and includes, reproduce it with an Identity template: <xsl:template match="@* | *"> <xsl:copy> <xsl:apply-templates select="@* | node()" mode="#current"/> </xsl:copy> </xsl:template>
Guys,
I had this issue, which I solved, but thought someone here could probably recreate with some better ideas?? I did not refractor this.. so , I am sure the code can be refractored or rearranged/ beautified .. But I am wanting to see if there is a completely different approach...
The problem is as folllows..
XSLT is written for an XSD. This XSD may include another XSD and that may include more XSDs and so on and so forth,. This can end up becoming a huge tree. Some where, one of the XSDs can actually refer to another XSD which could have been already in the tree. So a normall thought process is that your XSLT will fail because it will end up into the infinite recursion ( circular reference).. So I wrote this XSLT to process such a tree... I have simulated this one with XMLS with nodes that are called<includes> //
Main XML : ======= <xml1> <includes>file1.xml</includes> <includes>file2.xml</includes> </xml1>
file1.xml ======= <xml1> <includes>file1.1.xml</includes> <includes>file1.2.xml</includes> </xml1>
file2.xml ======= <xml1> <includes>file2.1.xml</includes> <includes>file2.2.xml</includes> </xml1> file1.1.xml ======= <xml1> <includes>file1.1.1xml</includes> <includes>file1.xml <!-- this one is bad circular reference --> </includes> </xml1>
and so on...
The XSLT is ========
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> <xsl:template match="xml1"> <xsl:call-template name="get-include"> <xsl:with-param name="init" select="0"/> </xsl:call-template> </xsl:template> <xsl:template name="get-include"> <xsl:param name="document-name"/> <xsl:param name="init"/> <xsl:param name="include-tree"/> <xsl:choose> <xsl:when test="$init = 1"> <xsl:for-each select="document($document-name)//includes"> <xsl:variable name="doc-name" select="."/> <xsl:value-of select="."/> <xsl:choose> <xsl:when test="contains($include-tree,$doc-name)"> <xsl:text>: This file is ignored : Circular Reference</xsl:text> <xsl:text>
</xsl:text> </xsl:when> <xsl:otherwise> <xsl:text>,</xsl:text> <xsl:call-template name="get-include"> <xsl:with-param name="document-name" select="$doc-name"/> <xsl:with-param name="init" select="1"/> <xsl:with-param name="include-tree"
select="concat($include-tree,'/',$doc-name,'/')"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> <xsl:text>
</xsl:text> </xsl:for-each> </xsl:when> <xsl:otherwise> <xsl:for-each select="//includes"> <xsl:text> 
</xsl:text> <xsl:variable name="doc-name" select="."/> <xsl:value-of select="."/> <xsl:call-template name="get-include"> <xsl:with-param name="document-name" select="."/> <xsl:with-param name="init" select="1"/> <xsl:with-param name="include-tree" select="concat($include-tree,'/',$doc-name)"/> </xsl:call-template> </xsl:for-each> </xsl:otherwise> </xsl:choose> </xsl:template>
</xsl:stylesheet>
Any Ideas??
Vasu Chakkera
-- Gerrit Imsieke Geschdftsf|hrer / Managing Director le-tex publishing services GmbH Weissenfelser Str. 84, 04229 Leipzig, Germany Phone +49 341 355356 110, Fax +49 341 355356 510 gerrit.imsieke@xxxxxxxxx, http://www.le-tex.de
Registergericht / Commercial Register: Amtsgericht Leipzig Registernummer / Registration Number: HRB 24930
Geschdftsf|hrer: Gerrit Imsieke, Svea Jelonek, Thomas Schmidt, Dr. Reinhard Vvckler
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Recursion, David Carlisle | Thread | [xsl] is there a more elegant way t, Terry Ofner |
Re: [xsl] Recursion, Vasu Chakkera | Date | [xsl] is there a more elegant way t, Terry Ofner |
Month |