This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 29458 - [xslt30ts] seqtor-027
Summary: [xslt30ts] seqtor-027
Status: RESOLVED FIXED
Alias: None
Product: XPath / XQuery / XSLT
Classification: Unclassified
Component: XSLT 3.0 Test Suite (show other bugs)
Version: Candidate Recommendation
Hardware: PC All
: P2 normal
Target Milestone: ---
Assignee: Abel Braaksma
QA Contact: Mailing list for public feedback on specs from XSL and XML Query WGs
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-02-14 17:20 UTC by Michael Kay
Modified: 2016-10-19 19:14 UTC (History)
1 user (show)

See Also:


Attachments

Description Michael Kay 2016-02-14 17:20:20 UTC
This is a tough one to analyze. I am getting a space before the "A". I think it's simpler to work out what's happening if we simplify the test by writing f:create(2) rather than f:create(61). In that case I get the result 

startend A BC

This follows the following logic, where CSC means "construct simple content", and CCC is "construct complex content:

1. The initial template creates a text node "start" followed by the results of f:create(2).

2. The result of f:create(2) is a text node whose string value is CSC(f:create(1)) followed by the string "C"

3. The result of f:create(1) is a text node whose string value is CSC(f:create(0)) followed by the string "B"

4. The result of f:create(0) is a text node whose string value is "end", followed by the string "A".

So the overall result is equivalent to

let $R4 := (text("end"), "A")
let $R3 := (text(CSC($R4)), "B")
let $R2 := (text(CSC($R3)), "C")
let $R1 := (text("start"), $R2)
return $R1

Now:

CSC($R4) is as follows:

1. Zero-length text nodes in the sequence are discarded. No change.

2. Adjacent text nodes in the sequence are merged into a single text node. No change.

3. The sequence is atomized (which may cause a dynamic error). => ("end", "A")

4. Every value in the atomized sequence is cast to a string. => ("end", "A")

5. The strings within the resulting sequence are concatenated, with a (possibly zero-length) separator inserted between successive strings. => "end A"

6. In the case of xsl:processing-instruction, any leading spaces in the resulting string are removed. N/A.

So $R3 is (text("end A"), "B")

CSC($R3), by similar logic to that above, is text("end A B")

So $R2 is (text("end A B"), "C")

So $R1 is (text("start"), text("end A B"), "C")

The final serialization step gives a result of

document-node(CCC(text("start"), text("end A B"), "C"))

Step 4 of CCC gives (text("start"), text("end A B"), text("C"))

Step 7 of CCC gives (text("startend A BC")

so the result is document-node("startend A BC")

which is the result that Saxon delivers.
Comment 1 Michael Kay 2016-02-14 17:36:09 UTC
The seqtor tests for which I get different results (I haven't analyzed them all in detail) are:

-s:seqtor -t:seqtor-027
Actual:'startend A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | }~'

-s:seqtor -t:seqtor-028
Actual:'startend A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | }~'

s:seqtor -t:seqtor-039a
Actual results:
<bar foo=" | | "/>

-s:seqtor -t:seqtor-039d
Actual results:
<bar foo="||"/>

-s:seqtor -t:seqtor-040a
Actual results:
<bar> | | </bar>

-s:seqtor -t:seqtor-040c
Actual results:
<bar> | | </bar>

-s:seqtor -t:seqtor-040d
Actual results:
<bar>||</bar>

-s:seqtor -t:seqtor-041
Error on line 16 of seqtor-041.xsl:
  XTTE0570: A sequence of more than one item is not allowed as the value of variable $foo
  (text(""), text(""), ...) 
Expected success, got error XTTE0570

-s:seqtor -t:seqtor-042
Error on line 16 of seqtor-042.xsl:
  XTTE0570: A sequence of more than one item is not allowed as the value of variable $foo
  (text("non-empty"), text(""), ...) 
Expected success, got error XTTE0570
Comment 2 Michael Kay 2016-02-14 21:32:20 UTC
Regarding seqtor-041 and -042:

seqtor-041 has

    <xsl:variable name="foo" as="text()">
        <!-- multiple empty text nodes are removed -->
        <xsl:text expand-text="yes">{ (:hello:) 'empty'[false()]}</xsl:text>
        <xsl:text/>
        <xsl:text expand-text="yes">{ (:hello:) 'empty'[false()]}</xsl:text>
    </xsl:variable>

There is nothing in the spec to justify the comment "multiple empty text nodes are removed". When xsl:variable has an "as" attribute, the value of the variable is the result of the sequence constructor, modified if necessary by applying the function conversion rules. The rules for constructing simple/complex content are not applied, therefore empty text nodes are not removed, therefore the raw value is a sequence of three text nodes and this fails the type check.

Similarly seqtor-042 - multiple text nodes are NOT combined unless CSC or CCC is invoked, and this only happens when the seqtor is used to construct the content of a node.
Comment 3 Michael Kay 2016-02-17 12:00:09 UTC
These tests have been fixed.
Comment 4 Michael Kay 2016-03-09 14:56:34 UTC
I am still seeing different results for seqtor-027 and -028.

Specifically I am still getting

-s:seqtor -t:seqtor-027
Actual:'startend A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | }~'

-s:seqtor -t:seqtor-028
Actual:'startend A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | }~'

but the expected results have no space between the final "}" and "~"
Comment 5 Michael Kay 2016-03-09 15:22:15 UTC
Sorry for the confusion.

The expected results for both tests end in 

x y z { | } ~

The actual results I am getting for both tests ends in

x y z { | }~

that is, without any space between the last two printable characters.

The recursive function is:

    <xsl:function name="f:create" as="item()+">
        <xsl:param name="i" as="xs:integer" />
        <xsl:text expand-text="yes">{if($i = 0) then 'end' 
            else f:create($i - 1)}</xsl:text>
        <xsl:sequence select="codepoints-to-string($i + 65)" />
    </xsl:function>

If we consider the first three calls, (X) the call create(61) returns (text(create(60)), &#126;); the call create(60) returns (text(create(59)), &#125;), and the call create(59) returns (text('....'), &#124;) where "...." is the result of further calls. Combining these results we have

So create(59) returns a text node('....') followed by a string("|").

text(create(59)) combines these using CSC to a text node ('.... |')

So create(60) returns a text node ('.... |') followed by a string("}")

text(create(60)) combines these using CSC to a text node ('.... | }')

create(61) returns this text node followed by the string "~".

These two items form part of the result of the initial template. They are combined using CSC. The CSC rules do not insert a space between a text node and a string, and therefore in the final result there should be no space preceding the final tilde.
Comment 6 Abel Braaksma 2016-03-09 16:26:39 UTC
I think you are right, the tests are failing for me as well, with:

Actual string  : startend A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | }~

So, indeed, no space before the final character for reasons of the order of unwinding the recursion. I will update the tests in the repo.
Comment 7 Michael Kay 2016-10-19 19:14:54 UTC
I believe that these problems have now been fixed.