Subject: Re: Recursion
From: Vasu Chakkera <vasucv@xxxxxxxxx>
Date: Mon, 28 May 2012 12:26:19 +0100
|
Thanks Mike.
I will look out for it.
Vasu
On 28 May 2012 12:17, Michael Kay <mike@xxxxxxxxxxxx> wrote:
> You will find some examples of how to look for cycles in a graph in my book
> XSLT 2.0 Programmers Reference, pp251-253 and 353-353 in the 4th edition.
>
> (Don't use the examples in the third edition, where I got them badly wrong!
> - which just goes to show that this problem is quite a tricky one.)
>
> The main differences are (a) I've generalized the solution by detecting
> cycles in ANY graph, using higher-order functions to parameterize the
> solution), and (b) the memory of where you've been in the graph is provided
> as a sequence, not a concatenated string.
>
> For this particular problem you also need to worry about turning the
> schemaLocation values into absolute URIs relative to their containing
> document, and checking for cycles after absolutizing the URI.
>
> Generally, though I would advise against trying to extract schema
> information from raw schema documents - you will get it wrong. It's much
> better to get the information from a schema processor that has already
> pre-digested the schema documents and turned them into a schema component
> model.
>
> Michael Kay
> Saxonica
>
>
> On 28/05/2012 11:58, Vasu Chakkera wrote:
>>
>> 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
>
--
Vasu Chakkera
NodeLogic Limited
Oxford
www.node-logic.com
==============
|