3

I am getting this from LibXSLT:

XSLTProcessor::transformToXml(): Invalid type
XSLTProcessor::transformToXml(): xmlXPathCompiledEval: 1 objects left on the stack.

I am passing a param which can either have a string value or a nodeset. I am trying to test whether it contains a certain substring and in that case assign that value to another parameter.

The calling template:

<xsl:call-template name="img">
    <xsl:with-param name="upload" select="'url.com/image.jpg'"/>
    <xsl:with-param name="w" select="200"/>
    <xsl:with-param name="h" select="200"/>
</xsl:call-template>

The called template:

<xsl:template name="img" match="*" mode="w">
    <xsl:param name="upload" select="."/>

    <xsl:param name="JITexternal">
        <xsl:choose>
            <xsl:when test="
                not($upload/meta) and (contains($upload, '.jpg')
                or
                contains($upload, '.png'))
                ">
                <xsl:value-of select="$upload"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="0"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:param>
</xsl:template>

While I am not sure what is tripping LibXSLT, I think is that fact that when I run those tests and the value is a string it throws the type error above.

But most importantly, is there a good way to test the type of a param's value?

UPDATE: the full XSL script on GitHub

msanford
  • 11,803
  • 11
  • 66
  • 93
tmslnz
  • 1,801
  • 2
  • 15
  • 24
  • 2
    @tmslnz: You should know the data type you are passing. There is no such thing as type checking in XSLT/XPath 1.0. That could be done in XSLT/XPath 2.0 but the reason is mainly schema-awareness and not what you are trying to do. –  Mar 25 '11 at 22:54
  • @Alejandro: Thanks. The strange thing is that I *think* that it worked before. But now, for some reason it trips out. Maybe converting the node to a string before testing? – tmslnz Mar 25 '11 at 23:06
  • @tmslnz: It's not clear why you want to use the param as primary expression for `$upload/meta` relative path instead of declaring `$upload` as being this `meta` element in the first place. That way you could use `meta` element' string value or some other literal string. –  Mar 26 '11 at 00:15
  • @Alejandro: The code above is part of a larger XSL utility template used with Symphony CMS. It is designed around the most common use case, which is the XML nodeset returned by an upload field. At times I want to pass an URL string value instead of a nodeset. I originally did it using two different params, but then decided to merge them into one, to simplify the *interface*. I have a updated the question with a link to the full XSL file hosted on Github. – tmslnz Mar 26 '11 at 00:24
  • @tmslnz: There is no problem in using a singleton node set or string for parameter as long as you operate over them with common denominator operators: string functions and no `/` path operator –  Mar 26 '11 at 00:33
  • 1
    Do note that you have provided a code sample that is obviously invalid: There is no `$upload` parameter defined for the template and the XSLT processor raises an error due to this. Your code is deeply misleading and confusing. Please, never ever do this again. Always provide the full code, so that people could repre the problem. – Dimitre Novatchev Mar 26 '11 at 16:18
  • 2
    @Dimitre-Novatchev: There was a mistake in the code I posted where `data` should have been `upload`. However my question had a broader scope than just that snippet of code. I also did provide the FULL code in a link to GitHub. You don't really want me to be posting 600+lines in here. Please chill out. – tmslnz Mar 27 '11 at 02:08
  • @Dimitre Novatchev, perhaps you could edit the question in keeping with the spirit of SO. – Ross Mar 29 '11 at 12:38

1 Answers1

3

While not exactly type checking, I found that converting the result tree fragment to a string() before running my test did prevent LibXSLT to bomb out:

    <xsl:param name="JITexternal">
        <xsl:choose>
            <xsl:when test="starts-with(string($upload), 'http://')">
                <xsl:value-of select="$upload"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="0"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:param>
tmslnz
  • 1,801
  • 2
  • 15
  • 24