Project

Profile

Help

XPTY0004: Cast does not allow an empty sequen

Added by Anonymous over 17 years ago

Legacy ID: #4243713 Legacy Poster: W. Eliot Kimber (drmacro)

I just moved from 8.4 to 8.9J and I'm now getting the subject message on this line: <xsl:if test="$label != ''"> The variable $label is set like so: <xsl:variable name="label" as="xs:string"> <xsl:choose> <xsl:when test="not(empty(preceding-sibling::label))" > <xsl:message>There is a label: <xsl:copy-of select="preceding-sibling::label"/></xsl:message> <xsl:value-of select="string(preceding-sibling::label)"/> </xsl:when> <xsl:otherwise> <xsl:message>no label.</xsl:message> <xsl:value-of select="''"/> </xsl:otherwise> </xsl:choose> </xsl:variable> Here's my message output (using Java 1.4.2_13): There is a label: <label mappable="inherit" superseded="no"/> ***label=// Error on line 468 of file:/C:/projects/northstar/xslt/legacy_conv/legacy2dita.xsl: XPTY0004: Cast does not allow an empty sequence It appears that calling string on an element with no content is resulting in an empty sequence, rather than a null string, which is certainly what's been happening up to now. This feels like a bug, either in Saxon or in the XSLT spec, if this is conforming behavior. Or am I just out of date with XSLT 2 and need to use a differen coding pattern for handling potentially-empty elements? Thanks, Eliot


Replies (11)

Please register to reply

RE: XPTY0004: Cast does not allow an empty se - Added by Anonymous over 17 years ago

Legacy ID: #4243728 Legacy Poster: W. Eliot Kimber (drmacro)

Follow up: saxon 8.8J does not produce the same failure, so it's definitely something new in 8.9 Cheers, Eliot

RE: XPTY0004: Cast does not allow an empty se - Added by Anonymous over 17 years ago

Legacy ID: #4243735 Legacy Poster: W. Eliot Kimber (drmacro)

Also, I just noticed that when I run the same transform from within Oxygen8.1, which reports it's using SaxonB 8.9.01, the transform works fine but when I run it from the command line with 8.9, it breaks. I'm using the -t option to report the saxon details. So something strange is going on.

RE: XPTY0004: Cast does not allow an empty se - Added by Anonymous over 17 years ago

Legacy ID: #4279912 Legacy Poster: W. Eliot Kimber (drmacro)

I am still getting this problem with the latest 8.9 downloaded from sourceforge. If i use 8.6 there is no problem. If I use 8.8 then I get a Java class cast exception on net.sf.saxon.value.StringValue. Here's my latest output (XSLT code is the same): Running transform... Saxon 8.9J from Saxonica Java version 1.5.0_11 Stylesheet compilation time: 887 milliseconds Processing file:/C:/projects/northstar/siberlogic_data/all-topics_master.xml Building tree for file:/C:/projects/northstar/siberlogic_data/all-topics_master.xml using class net.sf.saxon.tinytree.Ti nyBuilder Tree built in 30 milliseconds Tree size: 9 nodes, 0 characters, 1 attributes Building tree for file:/C:/projects/northstar/siberlogic_data/Balance%20Sheet%5B1%5D.f.w.xml using class net.sf.saxon.ti nytree.TinyBuilder Tree built in 409 milliseconds Tree size: 5966 nodes, 162042 characters, 10205 attributes preceding-sibling::label: <label superseded="no" mappable="inherit"/> *** $label = "" Error on line 488 of file:/C:/projects/northstar/xslt/legacy_conv/legacy2dita.xsl: XPTY0004: Cast does not allow an empty sequence Transformation failed: Run-time errors were reported Done. Surely this must be a bug in Saxon? Cheers, Eliot

RE: XPTY0004: Cast does not allow an empty se - Added by Anonymous over 17 years ago

Legacy ID: #4279940 Legacy Poster: Michael Kay (mhkay)

I can't reproduce the problem from the evidence you've provided (it works for me). Could you please supply enough code so I can run it here and reproduce the effect. You might not be aware that you're using string() to construct a string from an element node, you're then using xsl:value-of to turn the string into a text node, and you're then doing "as='xs:string'" to turn the text node back into a string. Try to get into the habit of using xsl:sequence rather than xsl:value-of unless you really do want a text node.

RE: XPTY0004: Cast does not allow an empty se - Added by Anonymous over 17 years ago

Legacy ID: #4279949 Legacy Poster: W. Eliot Kimber (drmacro)

Hmm. I can try to create a small failing test case, although I won't be able to do it today. But maybe I'm just not doing things the right way from an XSLT 2 standpoint. What I'm trying to do is test whether or not the data content of an element is or is not an empty string (including reducing whitespace-only content to ""). I'll review my code and see if I can correct it. Cheers, Eliot

RE: XPTY0004: Cast does not allow an empty se - Added by Anonymous over 17 years ago

Legacy ID: #4279998 Legacy Poster: W. Eliot Kimber (drmacro)

Ok, here's a small transform: <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" > <xsl:template match="/"> <xsl:apply-templates/> </xsl:template> <xsl:template match="doc"> <xsl:apply-templates/> </xsl:template> <xsl:template match="label"> <!-- WEK: Saxon 8.9 is producing an empty sequence with the label has no content --> <xsl:message>preceding-sibling::label: "<xsl:copy-of select="preceding-sibling::label"/>" </xsl:message> <xsl:variable name="label" as="xs:string" select="preceding-sibling::label"/> <xsl:message>*** $label = "<xsl:copy-of select="$label"/>"</xsl:message> <xsl:variable name="labelText"> <xsl:if test="$label != ''"> <xsl:value-of select="concat($label, ' ')"/> </xsl:if> </xsl:variable> <result><xsl:sequence select="$labelText"/></result> </xsl:template> </xsl:stylesheet> and an input doc: <?xml version="1.0" encoding="UTF-8"?> <doc> <label id="l-01">label one</label> <label id="l-02"/> </doc> When I run this I get this result: C:\projects\northstar\xslt\legacy_conv>....\scripts\labeltest.bat label-test.xml Running transform... Saxon 8.9J from Saxonica Java version 1.5.0_11 Stylesheet compilation time: 480 milliseconds Processing file:/C:/projects/northstar/xslt/legacy_conv/label-test.xml Building tree for file:/C:/projects/northstar/xslt/legacy_conv/label-test.xml using class net.sf.saxon.tinytree.TinyBuil der Tree built in 10 milliseconds Tree size: 9 nodes, 9 characters, 2 attributes preceding-sibling::label: "" Error on line 19 of file:/C:/projects/northstar/xslt/legacy_conv/label-test.xsl: XTTE0570: An empty sequence is not allowed as the value of variable $label Transformation failed: Run-time errors were reported My quick reading of "constructing simple content" suggests that constructing a string from an empty sequence should result in an empty string. Otherwise, you'd be forced to do an existence check on results of the select= value before trying to assign it to a variable. Or have I misread the spec? Cheers, Eliot

RE: XPTY0004: Cast does not allow an empty se - Added by Anonymous over 17 years ago

Legacy ID: #4280011 Legacy Poster: Michael Kay (mhkay)

>What I'm trying to do is test whether or not the data content of an element is or is not an empty string (including reducing whitespace-only content to "") That looks to me something like: <xsl:function name="f:hasEmptyContent" as="xs:boolean"> <xsl:param name="e" as="element()"/> <xsl:sequence select="not($e/* or normalize-space($e))"/> </xsl:function> depending on your exact definition. Michael Kay

RE: XPTY0004: Cast does not allow an empty se - Added by Anonymous over 17 years ago

Legacy ID: #4280021 Legacy Poster: W. Eliot Kimber (drmacro)

If I rework the "label" variable assignment like so: <xsl:variable name="label" as="xs:string"> <xsl:choose> <xsl:when test="preceding-sibling::label"> <xsl:message>*** there is a preceding-sibling label</xsl:message> <xsl:sequence select="preceding-sibling::label[1]"/> </xsl:when> <xsl:otherwise> <xsl:message>*** no preceding-sibling label</xsl:message> <xsl:sequence select="''"/> </xsl:otherwise> </xsl:choose> </xsl:variable> Then it works (I also realized that the above fails if I add a third label to the test doc because I wasn't limiting the select to a single node, but that's simple user error). If I leave the otherwise empty I get a "XTTE0570: An empty sequence is not allowed as the value of variable $label" when there is no preceding sibling, which is essentially the same condition as before. It still seems wrong, either per the spec or just in terms of how things should work that an empty sequence does not result in an empty string in this case. In particular, 9.3 says "If a variable-binding element has an as attribute but no select attribute, then the supplied value is the sequence that results from evaluating the (possibly empty) sequence constructor contained within the variable-binding element (see 5.7 Sequence Constructors)." So the spec specifically allows empty sequences/sequence constructors. That suggests this is a bug in how Saxon is constructing strings from empty sequences. Cheers, Eliot

RE: XPTY0004: Cast does not allow an empty se - Added by Anonymous over 17 years ago

Legacy ID: #4280026 Legacy Poster: Michael Kay (mhkay)

Your repro is failing on the line <xsl:variable name="label" as="xs:string" select="preceding-sibling::label"/> when applied to the first label. This label has no preceding label, so the select expression returns (). Under the function conversion rules, which are also used by xsl:variable, it attempts to convert () to a string but this fails: neither atomization nor numeric promotion will get you from () to a string. Casting would also fail, while the string() function would succeed, but these are both stronger conversions than the system is prepared to apply automatically. Change it to <xsl:variable name="label" as="xs:string" select="string(preceding-sibling::label)"/> Michael Kay

RE: XPTY0004: Cast does not allow an empty se - Added by Anonymous over 17 years ago

Legacy ID: #4280045 Legacy Poster: W. Eliot Kimber (drmacro)

Hmmm. OK. That's a very subtle distinction. I guess I would intuitively expect as="xs:string" and string() to have the same effect. But problem solved. Thanks, Eliot

RE: XPTY0004: Cast does not allow an empty se - Added by Anonymous over 17 years ago

Legacy ID: #4280063 Legacy Poster: W. Eliot Kimber (drmacro)

Actually, problem not entirely solved. In my real transform, using the new mechanism for setting the "label" variable, I still get this failure: Error on line 481 of file:/C:/projects/northstar/xslt/legacy_conv/legacy2dita.xsl: XPTY0004: Cast does not allow an empty sequence On this line: <xsl:if test="$label != ''"> But I don't get that failure in my small test case and at this point in the code $label should be a string (or a sequence of one string?). I don't see any other obvious differences between the two environments. So something else must be going on but I have no idea what it might be. I'll see if I can put together a reasonably small test case. Eliot

    (1-11/11)

    Please register to reply