Hi Guys, I'm running into a problem where my imported func:function elements are generating "javax.xml.transform.TransformerException: func:function element must be top level" which doesn't make sense. My understanding is that the whole point is to use imports with func:function since you want to create libraries of reusable code.
I built the examples from http://www.exslt.org/func/elements/function/index.html as both inline function (the example given) and as imports. I've attached both here so you can see what the problems are. The following seems to work (no exceptions thrown): java org.apache.xalan.xslt.Process -in source.xml -xsl inline.xsl -out inline.xml The following doesn't work: java org.apache.xalan.xslt.Process -in source.xml -xsl test.xsl -out test.xml The exception thrown is: file:///V:/Xalan/lib.xsl; Line #7; Column #42; XSLT Error (javax.xml.transform.TransformerConfigurationException): javax.xml.transform.TransformerException: javax.xml.transform.TransformerException: func:function element must be top level. I'm not sure what is causing the error (the import routine perhaps?) since I don't know enough Java to dig around that far into the source code. I've encountered another problem. If you do: java org.apache.xalan.xslt.Process -in source.xml -xsl inline_with_variable.xsl -out inline.xml You will get: file:///V:/Xalan/inline_with_variable.xsl; Line #20; Column #18; XSLT Error (javax.xml.transform.TransformerConfigurationException): javax.xml.transform.TransformerException: javax.xml.transform.TransformerException: misplaced literal result in a func:function container. The literal is causing the problem is (by virtue of removing this variable eliminates the problem): <xsl:variable name="tfilepath"> <xsl:choose> <xsl:when test="contains($ref, '#')"> <xsl:value-of select="substring-before($ref, '#')"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="$ref"/> </xsl:otherwise> </xsl:choose> </xsl:variable> Since the value-of is a descendant of a variable this should never cause a problem. The problem here seems to be in the following snippet from org.apache.xalan.processor.ProcessorExsltFunction.validate: if (elem instanceof ElemValueOf || (elem instanceof ElemLiteralResult || elem instanceof ElemElement) && !(ancestorIsOk(elem))) This is like saying: if (x || y && !z) And I'm not sure the logic is explicit enough to be correct. Not to mention the fact that the grouping seems to be a little odd. It would be better, I think to use: if ((elem instanceof ElemValueOf || elem instanceof ElemLiteralResult || elem instanceof ElemElement) && !(ancestorIsOk(elem))) Your validation in incomplete. The EXSLT pages for func: says: Begin Quote: Function Results The content of the func:function element is a template. When the function is called, the template is instantiated to give the result of the function. The template is instantiated with the context node from the expression in which the function was called as the current node, and with the context node list from the expression in which the function was called as the current node list. It is an error if the instantiation of the template results in the generation of result nodes. ... :End Quote Now my reading of this suggests that you should also invalidate for anything that results in a node of any sort being generated. You should be checking for: xsl:element xsl:attribute xsl:text xsl:processing-instruction xsl:comment xsl:copy xsl:value-of xsl:number xsl:apply-templates xsl:apply-import xsl:call-templates xsl:text All these should fail unless they are children of result, param or variable. Now the if statement from above (if my quick survey of the source code was correct): if((elem instanceof ElemApplyImport || elem instanceof ElemApplyTemplates || elem instanceof ElemAttribute || elem instanceof ElemCallTemplate || elem instanceof ElemComment || elem instanceof ElemCopy || elem instanceof ElemCopyOf || elem instanceof ElemElement || elem instanceof ElemLiteralResult || elem instanceof ElemNumber || elem instanceof ElemPI || elem instanceof ElemText || elem instanceof ElemTextLiteral || elem instanceof ElemVariable) && !(ancestorIsOk(elem))) I hope this helps. H. Adam van den Hoven Web Developer Credit Union Central of BC p 604 7306380 e [EMAIL PROTECTED]
<?xml version="1.0"?> <doc> <section index="section1" index2="atr2val"> <section index="subSection1.1"> <p>Hello</p> <p>Hello again.</p> </section> </section> <section index="section2"> <p>Hello2</p> <section index="subSection2.1"> <p>Hello</p> <p>Hello again.</p> </section> <section index="subSection2.2"> <p>Hello</p> <p>Hello again.</p> </section> <p>Hello2 again.</p> <section index="subSection2.3"> <p>Hello</p> <p>Hello again.</p> </section> </section> </doc>
inline_with_variable.xsl
Description: inline_with_variable.xsl
lib.xsl
Description: lib.xsl
inline.xsl
Description: inline.xsl
