[Xsltforms-support] "xps" template and my old xalan problem.
Brought to you by:
alain-couthures
|
From: Christian M. <ch...@gm...> - 2010-03-09 17:26:42
|
I think I have located the problem why xalan gets a stack overflow error
when transforming a xform with a lot of xpath expressions. As fas as I
understand the xps template gets a long string which contains all
concatenated xpath expressions to transform to javascript. the xps template
gets recursively called with the remaining rest of the string. The parameter
containing the string has to be created each recursion on the stack.
and eventually it gets to small or something else happens such that the
recursion doesn't finish correctly.
I have tested that the occurrence of this problem depends only on the number
of xpath expressions not on the kind. There is a point on which the
transform fails if I add any attribute to the form.
If I remove the recursion the transform finishes (giving an unusable
result). I do not understand the code enough yet to replace it with
something that would work for me. But I expect that this recursion could be
transformed into a for-each loop by using something like tokenize(). or
store the xpaths into a result tree fragment and using the node-set()
function.
I really want this to work on existdb and xalan because then I do not have
to care about the performance any more as I would be able to serve a
precompiled html-javascript page instead of doing the very slow
xslttransform. If it takes a minute to redo the transform when I change the
xforms -- I think I can live with that. Saxon9 is unfortunately not saving
me because it fails too (and faster). Only saxon6.5 comes back with the
result but Saxon6.5 is not supported by existdb (as far as I know).
Thanks for all the help so far, and keep up the great work.
<xsl:template name="xps">
<xsl:param name="ps"/>
<xsl:param name="prep"/>
<xsl:variable name="xplen" select="substring-before($ps,'.')"/>
<xsl:variable name="xp"
select="substring(substring-after($ps,'.'),1,number($xplen))"/>
<xsl:if test="$xp != $prep">
<xsl:variable name="r">
<xsl:call-template name="xpath">
<xsl:with-param name="xp" select="$xp"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="$r"/>
</xsl:if>
<xsl:variable name="ps2"
select="substring($ps,string-length($xplen)+2+number($xplen))"/>
<xsl:if test="$ps2 != ''">
<xsl:call-template name="xps">
<xsl:with-param name="ps" select="$ps2"/>
<xsl:with-param name="prep" select="$xp"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
|