This is a TODO file for XSL-T 2.0 support.+ −
+ −
- LHF:+ −
* Warning bug, last parameter is always whined about.+ −
* Box in comment/PI/text/ws(?) handling -- pending Matthias+ −
* type036 -- namespace on top element isn't copied+ −
* XTDE0865+ −
* Attend XSLTTokenizer::isXSLT()+ −
* Remove redundant set() calls in setFocusHelper().+ −
+ −
- Missing features:+ −
General Priority+ −
---------------------+ −
* 1.0 QXmlQuery::evaluateTo(QIODevice *) P1 DONE+ −
* 1.0 Test suite integration P1 DONE+ −
* 1.0 xsl:key P1+ −
* 1.0 fn:key() P1+ −
* 1.0 2.0 Compatibility mode P1+ −
* 1.0 Regular parameters in templates P1+ −
* 1.0 xsl:include P1+ −
* 1.0 xsl:copy-of P1+ −
* 1.0 xsl:copy P1+ −
* 1.0 xsl:import P1+ −
* 1.0 fn:format-number P1+ −
* 1.0 xsl:message P2+ −
* 1.0 fn:current() P1 DONE+ −
* 2.0 fn:type-available() P3 DONE+ −
* 2.0 xsl:use-when P3+ −
* 2.0 fn:unparsed-entity-uri() P3+ −
* 2.0 fn:unparsed-entity-public-id() P3+ −
* 2.0 Tunnel Parameters P3+ −
* 2.0 xsl:attribute-set P3+ −
* 1.0 xsl:decimal-format P2+ −
* 1.0 xmlpatterns: initial template P1 DONE+ −
* 1.0 xsl:number P1+ −
* 1.0 Complete handling of xsl:sort P2+ −
* 2.0 Grouping+ −
- fn:current-group()+ −
- fn:grouping-key()+ −
- xsl:for-each-group()+ −
* 2.0 Regexp+ −
- xsl:analyze-string+ −
- xsl:matching-substring+ −
- xsl:non-matching-substring+ −
- fn:regex-group()+ −
* 2.0 Date & Time formatting+ −
- fn:format-dateTime()+ −
- fn:format-date()+ −
- fn:format-time()+ −
+ −
Serialization & Output:+ −
----------------------+ −
* 1.0 xsl:output+ −
--- Tie together serialization. Should we add+ −
QXmlQuery::evaluateTo(QIODevice 1.0 const) ?+ −
* 2.0 xsl:character-maps+ −
* 2.0 xsl:character-map+ −
* 2.0 xsl:result-document+ −
--- Should the "default output" be handle with xsl:result-document? Would+ −
depend on compilation.+ −
+ −
Optimizations:+ −
* Remove adjacent text node constructors+ −
* Remove string-join when first arg's static cardinality is not more than one+ −
* Remove string-join when the second arg is statically known to be the empty string.+ −
* Remove string-join when the second arg is a single space and the parent is a text node ctor.+ −
* Rewrite to operand if operands are one. What about type conversions?+ −
* Replace lookups with xml:id with calls on id().+ −
* Recognize that a/(b, c) is equal to a/(b | c). The later does selection and node sorting in one step.+ −
* Remove LetClause which has empty sequence as return clause, or no variable dependencies at all.+ −
* Do a mega test for rewriting /patterns/:+ −
"node() | element()" => element()+ −
"comment() | node()" => comment()+ −
+ −
and so forth. This sometimes happens in poorly written patterns. How does+ −
this rewrite affect priority calculation?+ −
+ −
Tests:+ −
* xml:id+ −
- Come on, the stuff needs to be reorganized xml:id.+ −
- Read in xml:id document with whitespace in attrs, write the doc out. Attrs should be normalized.+ −
- Do lookups of IDs with xml:id attrs containing whitespace.+ −
+ −
* current()+ −
- Use current() inside each instruction+ −
- In a template pattern+ −
- Several invocations: current()/current()/current()+ −
+ −
+ −
* Diagnosticsts:+ −
- See http://www.w3.org/Bugs/Public/show_bug.cgi?id=5643 . Comments+ −
should be taken into account when comparing. This suggests that we+ −
don't have any test which produces a document with XML comments.+ −
+ −
* element-available()+ −
- Review the tests.+ −
- Try using declarations in XSL-T, should return false+ −
- Use xsl:variable(both instr and decl)+ −
- invoke with all the XSL-T instructions.+ −
- Should return false for when, otherwise, matching-substring, non-matching-substring, etc?+ −
- Supply the namespace in the name via the default namespace, no prefix.+ −
+ −
* unparsed-text()+ −
- Load an empty file+ −
- Use a fragment in the URI+ −
- Use an invalid URI+ −
- Use device bindings and a QRC to ensure that we're not using a generic+ −
network manager.+ −
- Duplicate all the network tests. Same as for doc()+ −
+ −
* unparsed-text-available()+ −
- Same as for unparsed-text()+ −
+ −
* Sequence constructor that contains only:+ −
- XML comment+ −
- whitespace text node+ −
- processing instruction+ −
- a mix of the three+ −
+ −
* xsl:function+ −
- Ensure that it's not it's not in scope for use-when.+ −
- xsl:function/xsl:param: use processing instructions, whitespace and comments as child: should be stripped+ −
- Use <xsl:function/> : @name missing.+ −
- Don't strip ws, and have ws between two xsl:param, and between xsl:function and xsl:param.+ −
- Use xsl:function with no body.+ −
- use xsl:param/@tunnel = no+ −
- use xsl:param/@tunnel = yes+ −
- use an invalid value for xsl:param/@tunnel = yes+ −
- Have a non-WS text node in xsl:function/xsl:param/+ −
- Have a WS text node in xsl:function/xsl:param/+ −
- Have a WS text node in xsl:function/xsl:param/ while preserving WS.+ −
- use a comment as child of xsl:param+ −
- use a PI as child of xsl:param+ −
- XTSE0770 with import precedence and all that.+ −
- have two identical function in the stylesheet. The last has override=no. Should still report XTSE0770.+ −
- have @override with invalid value.+ −
- have whitespace inside xsl:param with different strip modes.+ −
- Have @select => error+ −
- Have body => error+ −
- call current() inside body. XPDY0002?+ −
+ −
* Does xml:base/StaticBaseURI and StaticCompatiblityStore prevent proper+ −
type checking due to expectedOperandTypes() returns item()*?+ −
+ −
* xsl:template/xsl:param+ −
- Have @required=yes, and have @select => error+ −
- Have @required=yes, and have body => error+ −
- Have a variable reference in a template after another, which has+ −
param, to ensure they aren't in scope.+ −
+ −
* xsl:template/@match+ −
- Have a pattern with unions, and have a body which relies on its+ −
static type.+ −
+ −
* @version:+ −
Have @version on *all* attributes.+ −
+ −
* xsl:call-template+ −
- Have a variable reference just after a xsl:call-template which has+ −
with-param, to ensure they aren't in scope.+ −
- Have an xsl:with-param which isn't used in the template. Error?+ −
- Have an xsl:with-param that has a type error.+ −
- an xsl:with-param is not in scope for the next one. Test this => error.+ −
- Have a call:template, whose with-param computes its value by calling+ −
another template, while using an with-param too.+ −
+ −
* XQuery:+ −
- DONE Ensure namespace {expr} {expr} is flagged as invalid+ −
- Use all XSL-T functions: error. Or we do that already?+ −
- Ensure order by collation 1 + 1 is an error+ −
- Ensure order by collation {1 + 1} is an error+ −
+ −
* document()+ −
- Basic node deduplication, no test exists for that.+ −
+ −
* xsl:perform-sort+ −
- Have no xsl:sort. Error. Must be at least one.+ −
- have xsl:sort with invalid value.+ −
- sort atomic values.+ −
- Trigger "The stable attribute is permitted only on the first xsl:sort element within a sort key specification"+ −
- have xsl:sort with no select and no seq ctor.+ −
- trigger the delegated queueing. All instructions inside.. xsl:sort?+ −
- have multiple sort statements, with the last being <xsl:sort/> only.+ −
- have WS between xsl:sort that is not ignorable.+ −
- Use a variable reference whose name is equal to our synthetic name. This should be XPST0008, but probably isn't.+ −
- Have an invalid value in xsl:sort/order. Use space+ −
- have xsl:sort return numbers, but data-type specify string.+ −
- have an AVT in xsl:sort/@lang+ −
- have an AVT in xsl:sort/@case-order+ −
- have an AVT in xsl:sort/@data-type+ −
- have an AVT in xsl:sort/@stable+ −
- Have mixed result, and hence incorrectly trigger XPTY0018 which the code currently raise.+ −
- Depend on the context position inside xsl:sort, when being child of+ −
perform-sort. Currently we create singleton focuses(I think), while+ −
we want the focus to be over the whole input sequence, not on indivual items.+ −
- Have <xsl:perform-sort select="valid-expr"/>: xsl:sort is missing+ −
- Use current() in the xsl:sort and the body, to ensure the right scope is picked up+ −
+ −
* xsl:copy-of+ −
- Have a text node. It's not allowed.+ −
- Have PIs, comments, and ignorable whitespace as children. Sigh.+ −
+ −
* xsl:namespace+ −
- Use xsl:fallback.+ −
- Use xsl:namespace inside xsl:variable and introspec the result in various+ −
ways. This is a big area, we don't have namespace nodes in XQuery. Yes, calling evaluateSingleton() will probably crash.+ −
- Use no select and no body, error: XTSE0910+ −
- Have name expression evaluate to the empty sequence.+ −
+ −
* Sequence ctor that:+ −
- Has invalid element in XSL namespace. E.g, xsl:foo+ −
+ −
* xsl:import+ −
- Have element as child as xsl:import: disallowed.+ −
- Have text as child as xsl:import: disallowed.+ −
- Have PIs and comments as child as xsl:import: allowed.+ −
+ −
* xsl:include+ −
- Have element as child as xsl:include: disallowed.+ −
- Have text as child as xsl:include: disallowed.+ −
- Have PIs and comments as child as xsl:include: allowed.+ −
+ −
* xsl:strip-space+ −
- Have PIs, comments, whitespace as child.+ −
+ −
* xsl:element+ −
- Extract EBV from result.+ −
- Use space in validation element.+ −
+ −
* xsl:perform-sort+ −
- Have PIs and comments in between xsl:sort elements.+ −
+ −
* xml:space+ −
- We never pop our stack. Fix the bug, and ensure we have tests for it.+ −
+ −
* fn:unparsed-entity-uri+ −
- Check type of return value+ −
- Do basic unparsed-entity-uri("does-not-exist")+ −
+ −
* fn:unparsed-entity-public-id+ −
- Do basic unparsed-entity-uri("does-not-exist"), two permutations, check the spec+ −
+ −
* xsl:element+ −
- Use disallowed attribute: select+ −
- use unknown type in @type+ −
- Use @namespace, but be not in the lexical space of xs:anyURI+ −
- use disallowed enumeration in @validation+ −
- have a name expression that evaluates to a xs:QName value as opposed to a string.+ −
- have a name expression that evaluates to a xs:QName value as opposed to a string. but+ −
also have the namespace attribute+ −
+ −
* xsl:attribute+ −
- Use disallowed attribute: match+ −
- use unknown type in @type+ −
- Use @namespace, but be not in the lexical space of xs:anyURI+ −
- use disallowed enumeration in @validation+ −
- have a name expression that evaluates to a xs:QName value as opposed to a string.+ −
- have a name expression that evaluates to a xs:QName value as opposed to a string. but+ −
also have the namespace attribute+ −
+ −
* xsl:template+ −
- Use the union keyword, it's forbidden, only "|" is allowed+ −
- Use an expression other than Literal and VarRef in KeyValue[8]+ −
- use a function other than key().+ −
- have a declaration that only can apperar as a child of xsl:stylesheet.+ −
- Have an element in the XSL-T namespace, but which is invalid, e.g "bar"+ −
- Use an axis other than child or attribute in pattern.+ −
- Have a template that no no match and no name attribute., XTSE0500+ −
- use child::document-node() in pattern+ −
- use @foo/child in pattern+ −
- apply templates to parentless attributes.+ −
- Have 3e3 in @priority+ −
- Have a @match with more than two alternatives, e.g "a | b | c", and have them all actually matching.+ −
- Use an XML name in the mode so we trigger+ −
NCNameConstructor::validateTargetName()+ −
- A template which only has a non-WS text node.+ −
- A template with param, followed by text node.+ −
+ −
* Simplified stylesheet+ −
- Use @version attribute only on doc element. Should fail, since @{XSL-T]version must be present+ −
+ −
* fn:current()+ −
- Have <xsl:value-of select="current()"/>+ −
+ −
* xsl:variable have a variable reference appearing before its global declaration, and then somehow trigger recursion.+ −
* xsl:choose+ −
- elements/nodes intermixed with xsl:choose/xsl:when+ −
- invalid attribute on xsl:choose+ −
- invalid attribute on xsl:when+ −
- invalid attribute on xsl:otherwise+ −
- invalid attribute on xsl:if+ −
- invalid attribute on xsl:template+ −
- invalid attribute on xsl:stylesheet+ −
- invalid attribute on xsl:transform+ −
- xsl:otherwise in the middle between xsl:when elements.+ −
- use namespace declarations on xsl:when+ −
- use namespace declarations on xsl:otherwise+ −
- use namespace declarations on xsl:choose+ −
+ −
* Namespaces:+ −
- Have:+ −
<xsl:sequence xmlns:bar="http://example.com/" select="1"/>+ −
<xsl:sequence select="bar:foo()"/>+ −
+ −
* XPath+ −
- For each XQuery-specific expression, add a test using that expression:+ −
- typeswitch+ −
- let+ −
- validate+ −
- extension expression+ −
- unordered+ −
- ordered+ −
- for+ −
- computed text node constructor+ −
- computed attribute constructor+ −
- computed comment constructor+ −
- computed PI constructor+ −
- computed element constructor+ −
- computed document constructor+ −
- direct element constructor+ −
- direct comment constructor+ −
- direct PI constructor+ −
- all declarations+ −
+ −
- Use all the predefined prefixes in XQuery; non are in XSL-T.+ −
+ −
* xsl:when+ −
- Use xml:space on it+ −
+ −
* xsl:otherwise+ −
- Use xml:space on it+ −
+ −
* xsl:version+ −
- Use letters, XTSE0110+ −
- Use a float: 2e3, XTSE0110+ −
- Use a weird number, 2.00000001+ −
+ −
* xsl:document+ −
- use disallowed attribute: select.+ −
- use unknown type in @type+ −
- use disallowed enumeration in @validation+ −
- What happens if the type in @type is unknown?+ −
- Use xml:base attr and check URI.+ −
+ −
* xsl:sequence+ −
- use match attribute+ −
+ −
* xsl:stylesheet+ −
- Use @xsl:default-collation on xsl:stylesheet. Shouldn't have any effect. Or?+ −
- Use an XSL-T instruction as child -- invalid.+ −
- Have an element in the XSL-T namespace, but which is invalid, e.g "foo"+ −
- Have xsl:default-collation="http://example.com/" on xsl:stylesheet+ −
- Use prefix local: in say a function name. Not allowed.+ −
- Use comments after document element.+ −
- XTSE0010: <xsl:invalid version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"/>+ −
- Change the version with @xsl:version on all elements that we have.+ −
+ −
* Patterns.+ −
- Basic */* test:+ −
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:template match="*/*"><xsl:sequence select="'MATCH'"/></xsl:template>+ −
+ −
+ −
</xsl:stylesheet>+ −
+ −
- Basic a/b test:+ −
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:template match="a/b"><xsl:sequence select="'MATCH'"/></xsl:template>+ −
+ −
+ −
</xsl:stylesheet>+ −
* xsl:strip-whitespace+ −
- Use a namespace prefix which is not unboudn+ −
- have a syntax error in one of the node tests+ −
+ −
* xsl:preserve-whitespace+ −
- Use a namespace prefix which is not unboudn+ −
- have a syntax error in one of the node tests+ −
+ −
* xsl:value-of+ −
- select attribute, and comment in body(error, XTSE0870)+ −
- select attribute, and processing instruction in body(error, XTSE0870)+ −
- select attribute, and CCDATA in body(error, XTSE0870)+ −
- select attribute, and element in body(error, XTSE0870)+ −
- use xsl:sequence in body. Default separator should be none.+ −
- use match attribute+ −
- use double apostrophes/quotes. How are they dealt with?+ −
+ −
* xsl:apply-templates+ −
- use match attribute+ −
- apply in a mode for which no templates are declared+ −
- apply in a mode which is mispelled for another.+ −
- Have: <xsl:apply-templates select="id('id2')/a | id('id5')"/>+ −
We CRASH+ −
+ −
* xsl:for-each+ −
- No body: <xsl:for-each select="abc"/>+ −
- No select attribute: <xsl:for-each>text</xsl:for-each>+ −
- Have mixed result, and hence incorrectly trigger XPTY0018 which the code currently raise.+ −
- Have:+ −
<xsl:for-each select="1, 'asd'">+ −
<xsl:sequence select="."/>+ −
</xsl:for-each>+ −
+ −
* xsl:variable+ −
- Test that function conversion rules are invoked+ −
- For what is an xsl:variable in scope? Where does the spec state it? Test+ −
that it is not in scope where applicable.+ −
- Have: <variable name="a" select=""/>+ −
+ −
* xsl:text+ −
- count the result of a template that has text node(non-ws),+ −
xsl:text(content), xsl:content(zero content), text node(non-ws+ −
- Have an element inside xsl:text: XTSE0010.+ −
- Use comments and PIs intermixed with text inside.+ −
+ −
* xsl:for-each+ −
- use match attribute+ −
- What should this produce? Saxon produces "123" but with xsl:text removed, "1 2 3".+ −
<xsl:template match="/">+ −
<xsl:for-each select="1 to 3">+ −
<xsl:sequence select="."/>+ −
<xsl:text></xsl:text>+ −
</xsl:for-each>+ −
</xsl:template>+ −
+ −
* xsl:if+ −
- Have <xsl:if test="">body</xsl:if>. Error+ −
- Have <xsl:if test="valid-test"/>. That is, empty body.+ −
+ −
* xsl:sequence+ −
- select attribute missing: <xsl:sequence/>+ −
- content other than xsl:fallback, e.g text node.+ −
- How do we sort?+ −
+ −
* for every state for XSL-T parsing:+ −
- Use invalid element that is in the XSL-T namespace.+ −
+ −
* In all cases expressions are queued/generated:+ −
- Trigger expression precedence bugs, due to lack of paranteses.+ −
+ −
* Use xml:space in stylsheeet that doesn't have value preserve nor default.+ −
* For each case we have while(!reader.atEnd()):+ −
- test that triggers parser error and that we detect it properly.+ −
+ −
* for every element that allows text:+ −
* Use CDATA. QXmlStreamReader distinguishes between the two. text before and after.:wa+ −
* Use XML Comments and split up text nodes.+ −
+ −
* Patterns:+ −
* Ensure node() doesn't match document nodes().+ −
* "//" is an invalid pattern+ −
* Is there some expression which has no children? findAxisStep()+ −
* Use @*/asdo+ −
* XPST0003: key(concat("abc", "def"), "abc")+ −
* XPST0003: id(concat("abc", "def"))+ −
* XPST0003: concat('abc', 'def') // WILL CRASH+ −
* XPST0003: unknownFunction()+ −
* Use double: key("abc", 3e3)+ −
* Use three argument key() in pattern.+ −
+ −
* Simplified stylsheet modules:+ −
* Omit the xsl:version attribute. XTSE0010+ −
+ −
* type-available()+ −
* We have no tests at all?+ −
+ −
* have xml:base on the following elements and check them with+ −
static-base-uri():+ −
- all instructions+ −
- all declarations, eg:+ −
- xsl:choose, xsl:choice, xsl:otherwise+ −
- xsl:template+ −
- xsl:function+ −
- etc+ −
+ −
Embedded stylesheet modules+ −
- Verify that we don't choke on xsl attrs with invalid attributes outside;+ −
"In an embedded stylesheet module, standard attributes appearing on+ −
ancestors of the outermost element of the stylesheet module have no effect."+ −
+ −
Parsing:+ −
- Error message for:+ −
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">+ −
<xsl:template match="/">+ −
<e/>+ −
</xsl:stylesheet>+ −
- Use the document "<do/" as focus.+ −
- Write a test for each call to checkForParseError();+ −
+ −
+ −
function-available:+ −
- Generally low coverage it seems.+ −
+ −
+ −
<xsl:template match="/"/> <!-- t0 -->+ −
<xsl:template match="*"/> <!-- t1 -->+ −
<xsl:template match="asd"/> <!-- t2 -->+ −
<xsl:template match="comment()"/> <!-- t3 -->+ −
<xsl:template match="a/b"/> <!-- t4 -->+ −
+ −
<xsl:apply-templates select="*"/>+ −
+ −
+ −
*(+ −
((/)/call-template(t0))+ −
(*/call-template(t1))+ −
(element(asd)/call-template(t2))+ −
(comment()/call-template(t3))+ −
(a/b/call-template(t3))+ −
)+ −
+ −
==>+ −
+ −
*/typeswitch(.)+ −
case $g0 as document-root() return call-template(t0)+ −
case $g0 as element() return call-template(t1)+ −
case $g0 as element(asd) return call-template(t2)+ −
case $g0 as comment() return (call-template(t3)+ −
case $g0 as a/b return (call-template(t4)+ −
+ −
+ −
Patterns are used in:+ −
- xsl:for-each-group/@group-starting-with+ −
- xsl:key/@match+ −
- xsl:number/(@count, @from)+ −
- xsl:template/@match+ −
+ −
+ −
+ −
c/b+ −
=>+ −
child-or-self::element(b)[parent::element(c)]+ −
+ −
c/b/a+ −
=>+ −
child-or-self::element(a)[parent::element(b)[parent::element(c)]]+ −
+ −
d/c/b/a+ −
=>+ −
child-or-self::element(a)[parent::element(b)[parent::element(c)[parent::element(d)]]]+ −
+ −
+ −
+ −
-----------------------------------+ −
<xsl:apply-templates select="foo"/>+ −
=>+ −
+ −
child::element(foo) map apply-template(#default)+ −
-----------------------------------+ −
+ −
-----------------------------------+ −
<xsl:apply-templates mode="yo" select="foo">+ −
<xsl:sort select="@bar"/>+ −
</xsl:apply-templates>+ −
=>+ −
+ −
let $g0 := for $g1 in child::element(foo)+ −
order by @bar+ −
return $g1+ −
return apply-template(yo)+ −
-----------------------------------+ −
+ −
-----------------------------------+ −
<xsl:perform-sort select="$in">+ −
<xsl:sort select="@sortKey"/>+ −
</xsl:perform-sort>+ −
+ −
=>+ −
+ −
sort $in/order by @sortKey+ −
-----------------------------------+ −
+ −
+ −
-----------+ −
+ −
John Snelson of Oracle Berkeley DB XML & XQilla writes in private mail:+ −
+ −
I'd had the same thought myself, too - you must be reading my mind ;-)+ −
+ −
What is he referring to?+ −
+ −
If one spends some time on fancy diagrams, QtXmlPatterns[LINK]'s, the XQuery+ −
engine that shipped in Qt 4.4, architecture looks like this:+ −
+ −
+ −
Recently I've started implementing XSL-T 2.0(hopefully to be done for Qt 4.5)+ −
and the whole approach to this is modifying the existing codebase as follows:+ −
+ −
+ −
+ −
+ −
+ −
+ −
Put differently, when QtXmlPatterns is dealing with XSL-T stylesheets, it+ −
replaces the XQuery tokenizer with a tokenizer which translates the+ −
stylesheet into XQuery tokens, that is consumed by the existing XQuery+ −
parser, extended with both grammar non-terminals and tokens to accomodate the+ −
XSL-T features that XQuery doesn't have. In compiler terms, it can be seen as+ −
an "extreme" frontend. Not only is the same intermediate representation used,+ −
the grammar is too.+ −
+ −
What is the point of this?+ −
+ −
The functional overlaps XQuery, XSL-T and others as well have is of course+ −
widely established. Even the specifications are at times generated from the+ −
same source documents, and that implementations subsequently modularize code+ −
is of course second nature to any engineer, and seen to some degree or+ −
another in contemporary implementations. Typically this happens in a+ −
traditional fashion, classes are re-used, their functionality widened to+ −
cover both/more languages. However, I believe doing it directly on the+ −
grammar level introduce several advantages.+ −
+ −
The parser is based on Bison and since it's not running in the experimental+ −
pull mode, it uninterruptedly calls the tokenizer. The tokenizer, class+ −
XSLTTokenizer, in turns calls an pull-based XML parser: QXmlStreamReader.+ −
What often complicate in ocassions like this is who that gets the right to+ −
call who, and who gets the convenience of tracking state in a natural way+ −
through a call stack.+ −
+ −
XSLTTokenizer is conveniently implemented: as it encounters declarations and+ −
instructions in the stylsheet, it recursively descends in the XSL-T grammar+ −
through its own functions, adding tokens to a queue, which is delivered to+ −
the parser when asked -- and when the queue is empty it resumes queuing+ −
tokens. The tokenizer is fairly crude, it queues up tokens for instructions+ −
uninterrupted, and only have states between declarations. Hence,+ −
XSLTTokenizer queues up tokens for each template and function body, but+ −
enters "delivery mode" inbetween. This of course periodically breaks+ −
streaming since it's buffering up tokens, but considering that the memory+ −
usage for tokens is low and that a finer granularity for states(say, being+ −
able to pop the stacks when being inbetween two xsl:when elements) requires a+ −
significant effort, this is fine until proven otherwise.+ −
+ −
+ −
Advantages+ −
---------------+ −
discuss analysis.+ −
+ −
+ −
XSLTTokenizer rewrite XSL-T to XQuery as follows:'+ −
+ −
Instructions+ −
-------------+ −
xsl:if An if/then/else expression whose else branch is the empty sequence+ −
+ −
xsl:choose: again, a nesting of if/then/else expressions+ −
+ −
xsl:value-of: a computed text node constructor. Its body contains a call to+ −
string-join() involving the separator attribute+ −
+ −
xsl:variable: a let/return binding. Since XSL-T is statement-like in its+ −
sequence constructors, parantheses are used to ensure the variable binding is+ −
in-scope for all subsequent statements.+ −
+ −
for-each: it is the iteration/mapping mechanism XQuery fails to supply,+ −
despite path steps and the FLWOR machinery. for-each iterates using a+ −
focus(which for doesn't, but paths do), but can do so over atomic values and+ −
unconditionally without sorting the result by document order(which paths+ −
can't/doesn't, but for do). For implementations that normalize paths into for+ −
loops as the formal semantics do, the approach is straight forward. In+ −
QtXmlPatterns' case, a synthetic token is queued which signals to create+ −
a "relaxed" path expression which skips halting on atomic values in its+ −
operands(XPTY0019) and also skips node sorting.+ −
+ −
All "direct" node constructors, like <myElement/>, and "computed" node+ −
constructors, like xsl:element, are all rewritten into the corresponding+ −
XQuery computed node constructors. In some cases direct node constructors+ −
could have been used, but in anycase the IR yielded is the same, and that+ −
computed constructors happen to use less tokens.+ −
+ −
A particular case is xsl:namespace, an instruction which doesn't have any+ −
corresponding expression in XQuery. In the case of QtXmlPatterns, the code+ −
obvious already have a notion of "create this namespace on this element", and+ −
an AST node was trivially added for fetching the namespace components+ −
computationally. However, the introduction of xsl:namespace in an XQuery+ −
implementation is not to be taken lightly wrt. to for instance testing, since+ −
it introduces a new node type.+ −
+ −
perform-sort: surprisingly this expression of all complicate matters, for the+ −
simple reason that its operands occur in the opposite order compared to+ −
XQuery when the input sequence is supplied through a sequence constructor,+ −
hence breaking the streamed approach. XSLTokenizer solves this by+ −
buffer: the attributes of the xsl:perform-sort elements are stored,+ −
the xsl:sort elements queued onto a temporary queue, and subsequently is+ −
either the select attribute or the sequence constructor queued, and the+ −
tokens for xsl:sort appended afterwards. This complicated code greatly, since+ −
XSLTokenizer had to be able to "move around" sequences of tokens.+ −
+ −
In addition perform-sort has the same problem as for-each, the iteration+ −
mechanism falls inbetween paths and the for loop. The focus for perform-sort+ −
is also the focus for the sequence constructor and the select attribute, but+ −
the focus for the xsl:sort elements is the initial sequence. This is+ −
approached by having a for loop, and where the expression in each order by+ −
clause has a relaxed path expression whose left operand is a variable+ −
reference to what the for loop bound.+ −
TODO Doesn't work. Focus size wrong.+ −
+ −
This is an approach that implementations of the "second generation" of the+ −
technologies can take. The bif difference is that XSL-T 2.0 doesn't have the+ −
restrictions of 1.0, more evident in XQuery's syntax.+ −
+ −
xsl:sort XSL-T is much more dynamic than XQuery through the use of templates,+ −
but also+ −
because more decisions can be taken at runtime through all attribute value+ −
templates. xsl:sort is surely a good example of this with its AVTs for+ −
language, order, collation, stability and what not. XQuery's order by stands+ −
in strong contrast, which has these coded in the grammar. In QtXmlPatterns'+ −
case, the AST node corresponding to order by was generalized to take things+ −
such as stability and order from operands. This is paid by the code paths in+ −
XQuery since for them are constants generated and inserted as operands even+ −
though its known at compile time what is needed. However, considering that+ −
these evaluations are not inside the actual sort loop, but instead only+ −
computed on each sort invocation, it shouldn't be too bad.+ −
+ −
xsl:message+ −
+ −
Templates+ −
-------------------------+ −
+ −
A big bucket of questions for an XQuery implementation is of course the+ −
introduction of templates. In this case it is too of large interest to+ −
rewrite relevant code into primitive XQuery expressions.+ −
+ −
Templates' drawback is often mentioned to be their dynamic nature which makes+ −
static inferences hard or impossible. However, by again rewriting in clever+ −
ways and making the code visible in a standard way, existing analysis code+ −
can operate upon it.+ −
+ −
For the purposes of this discussion, templates can be broken down into three+ −
distinct problems:+ −
+ −
A Finding what nodes to invoke upon. This is the expression found on+ −
xsl:apply-templates/@select, in the case of template rules+ −
+ −
B Concluding what template to invoke. This is the analyzis and evaluation of+ −
patterns, as found on xsl:template/@match, in the case of templates rules.+ −
This is seen as a critical, as for instance Michael Kay emphasizes in Saxon:+ −
Anatomy of an XSLT processor [LINK+ −
http://www.ibm.com/developerworks/library/x-xslt2/]+ −
+ −
C Invoking the template for the given context node+ −
+ −
For these three steps, the two first are specific to template rules, while the+ −
latter, invoking templates, can be seen to be treated identically regardless+ −
of kind: template rules as well as named templates.+ −
+ −
With this perspective as background, lets try to write it into XQuery+ −
primitives.+ −
+ −
First, all templates regardless of kind are instanciated by name. In the case+ −
of templates rules, a synthetic name is given. They are invoked by an XPath+ −
function named call-template() that as first argument takes the name of the+ −
template, and also handles template parameters. This "template callsite"+ −
which is separated from what it is invoked with and whether it is invoked,+ −
knows its target template statically, and hence can be subject to inlining,+ −
and usual functional analysis.+ −
+ −
Focus and concatenation of output handled.+ −
One should consider whether templates couldn't be considered as functions,+ −
with specialized arguments in the case of tunnel parameters.+ −
Knowing what templates will be invoked could be used to conclude+ −
node sorting is not necessary.+ −
Mention how we do builtin templates+ −
+ −
Attribute Value Templates+ −
-------------------------+ −
XSL-T make extensive use of Attribute Value Templates(AVTs), which are handled+ −
by turning the grammar piece in XQuery that is closest, into an expression.+ −
Simply, ExprSingle[32] is extended with the branch:+ −
+ −
AVT LPAREN AttrValueContent RPAREN+ −
+ −
where AVT is a synthetic token XSLTokenizer generates. This means that the+ −
code handling AVTs in XQuery's direct attribute constructors handles AVTs as+ −
generic expressions. AttrValueContent creates a call to the concat()+ −
function, over the operands.+ −
+ −
Deal with fn:current by using let $current := . return instruction.+ −
+ −
Another thing related to order and parsing is that XSL-T has more freedom wrt.+ −
to where variables are in scope. For instance, a variable declaration appearing+ −
after a user function declaration is in scope for the function in XSL-T, but+ −
that's not the case in XQuery. This means that delayed variable resolution must+ −
be added, something which wasn't, and cannot be active, for the XQuery code.+ −
See 9.7 Scope of Variables.+ −
+ −
The parser generates for the builtin template rules:+ −
+ −
declare template matches (text() | @*) mode #all+ −
{+ −
text{.}+ −
};+ −
+ −
*+ −
By having templates invocations essentially expressed as a callsite, or+ −
branching, allows control flow analysis in a traditional manner, and hence the+ −
possiblity to conclude what templates that are possibly invoked in various+ −
contexts (or not invoked). One good example where this could improve template+ −
matching is patterns containg predicates: let's say a template matches text+ −
nodes with a predicate, but , doh I'm wrong.+ −
+ −
The problem with expressing template invocation with if expressions, is finding+ −
ambiguous matches.+ −
+ −
Although normalizing down to a small set of primitives has its advantages, one+ −
problem is with doing it too early. When doing it directly when tokenization,+ −
the higher-level perspective is lost and therefore must be restored+ −
again(example?). For instance, if an error is reported in a primitive, it must+ −
not appear as originating from that primitive. It's not contstrained to error+ −
reporting(example?). However, this is a general problem when compilers shift+ −
between different representations.+ −
+ −
One effect this parsing approach has, is that the stylesheet cannot be used as+ −
an input document(e.g, what document("") would evaluate to); in that case it+ −
has to be parsed again. I think this is for the better; in the case that the+ −
stylsheet has this dual role, it means representations are used which are+ −
designed specifically for these respective roles. Although doing a dual parsing+ −
step is costly, it's somewhat relieved by that the input is typically cached at+ −
the byte level(file system and higher layers such as web/application caches) in+ −
the case of traditional file loading.+ −
+ −
Another problem is that the grammar is used to solve implementation details,+ −
and this might show as part of when the parser do error reporting.+ −
+ −
If one decide to not send XSL-T through the XQuery parser, it can be an+ −
advantage to have as little business logic as possible in the XQuery parser+ −
such that it can be reused.+ −
+ −
Some parts of XSL-T's syntax doesn't translate well to XQUery syntax. Some+ −
parts doesn't follow structure very strongly, surely not the structures that+ −
map well to XQuery's syntax. These are xml:base, @version and other attributes+ −
that can appear on any element. Their information needs to be preserved and+ −
need to affect the output code, but these cannot be done in a way which fits+ −
naturally with the XQuery syntax, and hence leads to workarounds. Have whole+ −
section on how we do @version and @xml:base. Another problem is namespace+ −
declarations on the top document element.+ −
+ −
What largely makes me believe this technique fails is that the large and most+ −
important parts, templates, instructions, maps well to XQuery, but the small+ −
but yet not ignorable details like @version and @xml:base does not, to the+ −
degree that the approach at large fails.+ −
+ −
fn:document()+ −
------------------------+ −
See class documentation for DocumentFN. Document what optimizations one typically+ −
wants to implement(const-fold on card 1, constant propagate).+ −
+ −
+ −
In other words, it's reasonable to believe that it's possible to extend the+ −
XQuery grammar such that it functionality wise is able to do the same as XSL-T,+ −
but this doesn't equal that it is a good way to reach every gritty corner of+ −
the XSL-T specification.+ −
+ −
Patterns+ −
--------------------+ −
The up-side-down turning, discuss id/key().+ −
+ −
Declarations+ −
---------------------+ −
xsl:function: the 'declare function' declaration. TODO override+ −
+ −
XSL-T's error codes goes against good refactoring. Its codes are+ −
specific on each usage, compared to for instance XPTY0004.+ −
+ −
Optimizations: string-join()/value-of+ −
+ −
<xsl:template match="document-node">+ −
<xsl:apply-templates select="child::element(doc)"/>+ −
</xsl:template>+ −
+ −
<xsl:template match="child-or-top::element(doc)"/>+ −
+ −
=>+ −
+ −
document-node()/child::element(doc) map apply-template+ −
+ −
matches child-or-top::element(doc)+ −
+ −
=>+ −
+ −
N/root(.)//(EE)+ −
+ −
N == document-node()+ −
EE == child::element(doc)+ −
+ −
=>+ −
+ −
document-node()/root(.)/descendant-or-self::node()/child::element(doc)+ −
+ −
Optimize out already in createCopyOf()+ −
+ −
Bugs:+ −
- DynamicContextStore and CurrentItemStore needs to implement+ −
evaluateToReceiver().+ −
- Don't we have a parsing bug in each place where we call insideSequenceConstructor(), and don't+ −
wrap the result in parantheses? E.g, a whitespace node followed by an instruction will lead to parse+ −
error if the parent is for instance xsl:when.+ −
+ −
In patterns we find:+ −
- Function :id()+ −
- Function :key()+ −
- AxisStep+ −
- GenericPredicate. Also used for paths.+ −
- (CombineNodes)+ −
- empty sequence; attribute::foo()/child::asd+ −
+ −
+ −
Test case, tokenizer asserts(fixed in 2a0e83b):+ −
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">+ −
+ −
+ −
<xsl:template match="/">+ −
<xsl:call-template name="TestFunction"/>+ −
</xsl:template>+ −
+ −
+ −
<xsl:template name="TestFunction">+ −
+ −
+ −
<xsl:call-template name="GetElem">+ −
<xsl:with-param name="element-set"select="$super/*"/>+ −
</xsl:call-template>+ −
+ −
</xsl:template>+ −
+ −
<xsl:template name="GetElem">+ −
<xsl:param name="element-set"/>+ −
<xsl:copy-of select="$element-set[@name]"/>+ −
</xsl:template>+ −
+ −
</xsl:stylesheet>+ −
+ −
Typing code:+ −
+ −
<xsl:stylesheet xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">+ −
+ −
<xsl:template match="/">+ −
+ −
<xsl:call-template name="templateName">+ −
<xsl:with-param name="a" select="2" />+ −
</xsl:call-template>+ −
+ −
</xsl:template>+ −
+ −
<xsl:template name="templateName">+ −
<xsl:param name="a" as="xs:integer"/>+ −
<xsl:sequence select="$a"/>+ −
</xsl:template>+ −
+ −
</xsl:stylesheet>+ −
+ −
Compat mode in attribute sets:+ −
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">+ −
+ −
<xsl:attribute-set name="attrSet" version="1.0">+ −
<xsl:attribute name="attributeName" select="1 + 'type error without compat mode'"/>+ −
</xsl:attribute-set>+ −
+ −
<xsl:template match="/">+ −
<out xsl:use-attribute-sets="attrSet"/>+ −
</xsl:template>+ −
+ −
</xsl:stylesheet>+ −
+ −
Space in mode:+ −
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">+ −
+ −
<xsl:template match="/">+ −
<xsl:apply-templates mode=" #default"/>+ −
</xsl:template>+ −
+ −
</xsl:stylesheet>+ −
+ −
+ −
Type error in global template:+ −
+ −
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">+ −
+ −
<xsl:variable name="wa" as="item()"/><!-- HERE, incorrect cardinality. -->+ −
+ −
<xsl:template name="templateName"/>+ −
+ −
</xsl:stylesheet>+ −
+ −
+ −
Variables are not in scope before its siblings:+ −
+ −
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">+ −
+ −
<xsl:template name="templateName">+ −
<xsl:sequence select="$var"/>+ −
<xsl:variable name="var" select="1"/>+ −
</xsl:template>+ −
+ −
</xsl:stylesheet>+ −
+ −
Crashes:+ −
+ −
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"+ −
xmlns:xs="http://www.w3.org/2001/XMLSchema"+ −
xmlns:local="http://example.com/"+ −
version="2.0">+ −
+ −
<xsl:variable name="var" as="xs:boolean">+ −
<xsl:value-of select="local:doesNotExist()"/>+ −
</xsl:variable>+ −
+ −
</xsl:stylesheet>+ −
+ −
+ −
+ −
Whitespace handling, the important part is WS after xsl:template:+ −
+ −
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">+ −
+ −
<xsl:template match="/" xml:space="preserve"><MATCH/></xsl:template>+ −
+ −
</xsl:stylesheet>+ −
+ −
+ −
+ −
Whitespace handling, preserve, but not inside xsl:apply-templates:+ −
+ −
<xsl:stylesheet xmlns:xsl="http://www.w2.org/1999/XSL/Transform" version="2.0">+ −
+ −
<xsl:template match="/" xml:space="preserve">MATCH<xsl:apply-templates>+ −
+ −
</xsl:apply-templates></xsl:template>+ −
+ −
</xsl:stylesheet>+ −
+ −
Have top-level xml:space, ensure whitespace as child of xsl:stylesheet is ignored:+ −
+ −
<xsl:stylesheet xml:space="preserve" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">+ −
+ −
<xsl:template match="/">MATCH<xsl:apply-templates>+ −
+ −
</xsl:apply-templates>+ −
</xsl:template>+ −
+ −
</xsl:stylesheet>+ −
+ −
Compat mode, Saxon & QtXmlPatterns fails:+ −
+ −
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">+ −
+ −
<xsl:template match="/">+ −
<xsl:sequence version="1.0" select="string-join(current-dateTime(), 'separator')"/>+ −
</xsl:template>+ −
+ −
</xsl:stylesheet>+ −
+ −
Compat mode, this is not in the suite:+ −
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">+ −
+ −
<xsl:template match="/">+ −
<xsl:sequence version="1.0" select="subsequence((1, 2), '2')"/>+ −
</xsl:template>+ −
+ −
</xsl:stylesheet>+ −
+ −
Crashes:+ −
+ −
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">+ −
+ −
<xsl:template match="doc"/>+ −
+ −
<xsl:apply-templates select="item" mode="crazy" />+ −
+ −
+ −
</xsl:stylesheet>+ −
+ −
Incorrectly yields compile error, XPST0003:+ −
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">+ −
+ −
<xsl:template match=""/>+ −
+ −
<xsl:apply-templates select="item" mode="crazy" />+ −
+ −
</xsl:stylesheet>+ −
+ −
Have a basic simplified stylesheet module:+ −
+ −
<output xsl:version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">+ −
<xsl:value-of select="/"/>+ −
</output>+ −
+ −
Have no @version:+ −
<output xsl:version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">+ −
<xsl:value-of select="/"/>+ −
</output>+ −
+ −
+ −
Is valid:+ −
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" >+ −
+ −
<xsl:template match="/">+ −
<xsl:perform-sort select=".">+ −
<xsl:sort select="*"/>+ −
<xsl:variable name="abc" select="b"/>+ −
</xsl:perform-sort>+ −
</xsl:template>+ −
+ −
</xsl:stylesheet>+ −
+ −
+ −
Is valid:+ −
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" >+ −
+ −
<xsl:template match="/">+ −
<xsl:perform-sort select=".">+ −
<xsl:sort select="*"/>+ −
TEXT+ −
</xsl:perform-sort>+ −
</xsl:template>+ −
+ −
</xsl:stylesheet>+ −
+ −
XTSE0020:+ −
<literalResultElement xsl:validation="disallowedValue"/>+ −
+ −
XTSE0020:+ −
<xsl:element name="localName" validation="disallowedValue"/>+ −
+ −
XTSE0805:+ −
<e xsl:disallowedAttribute=""/>+ −
+ −
not XPST0003, not in test suite:+ −
+ −
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">+ −
<xsl:template match="/">+ −
<xsl:variable name="s" as="element()*"/>+ −
</xsl:template>+ −
</xsl:stylesheet>+ −
+ −
Parsing of many exprs in xsl:value-of(with separator):+ −
+ −
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">+ −
+ −
<xsl:template match="/">+ −
<xsl:value-of separator="SEP">+ −
<xsl:sequence select="1"/>+ −
<xsl:sequence select="2"/>+ −
</xsl:value-of>+ −
</xsl:template>+ −
+ −
</xsl:stylesheet>+ −
+ −
+ −
Parsing of many exprs in xsl:value-of(without separator):+ −
+ −
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">+ −
+ −
<xsl:template match="/">+ −
<xsl:value-of>+ −
<xsl:sequence select="1"/>+ −
<xsl:sequence select="2"/>+ −
</xsl:value-of>+ −
</xsl:template>+ −
+ −
</xsl:stylesheet>+ −
+ −
+ −
Check type of empty variables:+ −
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"+ −
xmlns:xs="http://www.w3.org/2001/XMLSchema"+ −
version="2.0">+ −
+ −
<xsl:template match="/">+ −
<xsl:variable name="empty"/>+ −
+ −
<xsl:sequence select="'instance of xs:string:', $empty instance of xs:string, '(should be true)',+ −
'instance of document-node():', $empty instance of document-node(), '(should be false)',+ −
'value is:', $empty,+ −
'END'"/>+ −
+ −
</xsl:template>+ −
+ −
</xsl:stylesheet>+ −
+ −
+ −
Crashes:+ −
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">+ −
+ −
<xsl:template match="/">+ −
<e xmlns="ABC"/>+ −
</xsl:template>+ −
+ −
</xsl:stylesheet>+ −
+ −
+ −
invalid standard attributes on a simplified stylesheet module.+ −
+ −
+ −
+ −
+ −
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"+ −
xmlns:xs="http://www.w3.org/2001/XMLSchema"+ −
version="2.0">+ −
+ −
<!-- Type error: applying templates to a variable of type string -->+ −
<?spec xslt#applying-templates?>+ −
<?error XTTE0520?>+ −
+ −
<xsl:template match="/">+ −
<xsl:variable name="empty"/>+ −
+ −
<xsl:sequence select="'instance of xs:string:', $empty instance of xs:string, 'instance of document-node():', $empty instance of document-node()"/>+ −
+ −
</xsl:template>+ −
+ −
</xsl:stylesheet>+ −
+ −
+ −
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">+ −
+ −
<xsl:template match="/">+ −
<output>+ −
<xsl:sequence select="string-length(doesNotMatch)"/>+ −
</output>+ −
</xsl:template>+ −
+ −
</xsl:stylesheet>+ −
+ −
Asserts(not wellformed):+ −
+ −
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">+ −
<xsl:template match="/">+ −
<output>+ −
</outpu>+ −
</xsl:template>+ −
+ −
</xsl:stylesheet>+ −
+ −
+ −
From within a function, use the focus /through/ a variable reference:+ −
+ −
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:local="http://www.w3.org/2005/xquery-local-functions">+ −
+ −
<xsl:variable name="var" select="node()"/>+ −
+ −
<xsl:function name="local:function">+ −
<xsl:sequence select="$var"/>+ −
</xsl:function>+ −
+ −
<xsl:template match="/">+ −
<xsl:sequence select="local:function()"/>+ −
</xsl:template>+ −
+ −
</xsl:stylesheet>+ −
+ −
+ −
+ −
Loops infinitely:+ −
+ −
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">+ −
+ −
<xsl:template match="/" version="1.0">+ −
<xsl:namespace name="{doc/item}" select="'http://www.example.com'" version="1.0"/>+ −
</xsl:template>+ −
+ −
</xsl:stylesheet>+ −
+ −
+ −
Gives crash in coloring code:+ −
Stylesheet:+ −
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">+ −
+ −
<xsl:template match="/">+ −
</xsl:template>+ −
+ −
</xsl:stylesheet>+ −
+ −
Focus:+ −
<a><b/><</a>+ −
+ −
+ −
Should evaluate to true:+ −
+ −
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0">+ −
+ −
<xsl:template match="/">+ −
<xsl:call-template name="yo">+ −
<xsl:with-param name="arg" as="xs:integer">+ −
<xsl:sequence select="xs:untypedAtomic('1')"/>+ −
</xsl:with-param>+ −
</xsl:call-template>+ −
</xsl:template>+ −
+ −
<xsl:template name="yo">+ −
<xsl:param name="arg"/>+ −
<xsl:sequence select="$arg instance of xs:integer"/>+ −
</xsl:template>+ −
+ −
</xsl:stylesheet>+ −
+ −
Crashes, should be XTTE0570:+ −
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"+ −
xmlns:xs="http://www.w3.org/2001/XMLSchema"+ −
exclude-result-prefixes="xs" version="2.0">+ −
+ −
<xsl:template match="/">+ −
<xsl:apply-templates>+ −
<xsl:with-param name="second_seq" as="xs:string">+ −
</xsl:with-param>+ −
+ −
</xsl:apply-templates>+ −
</xsl:template>+ −
+ −
<xsl:template match="empty">+ −
<xsl:param name="second_seq">def</xsl:param>+ −
<xsl:sequence select="$second_seq instance of xs:string"/>+ −
</xsl:template>+ −
+ −
</xsl:stylesheet>+ −
+ −
* Parse error:+ −
+ −
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">+ −
+ −
<xsl:template match="/">+ −
<xsl:copy>+ −
<xsl:sequence select="1"/>+ −
<xsl:sequence select="2"/>+ −
</xsl:copy>+ −
</xsl:template>+ −
+ −
</xsl:stylesheet>+ −
+ −
* Write tests with xsl:with-param whose body is empty. That's effectively an+ −
empty sequence(?) which needs to be handled properly, and (dynamically) type+ −
checked correctly.+ −
+ −
--------------------------------------------------------------------------+ −
+ −
+ −
+ −
+ −
+ −
--------------------------------------------------------------------------+ −
+ −
+ −
+ −
-------------------------------------------------------------+ −
/a/b+ −
+ −
=>+ −
+ −
b[parent::a[parent::document()]]+ −
+ −
but we currently have:+ −
+ −
(b[parent::a])[parent::document()]+ −
+ −
-------------------------------------------------------------+ −
a/b+ −
+ −
=>+ −
+ −
b[parent::a]+ −
+ −
-------------------------------------------------------------+ −
a/b/c+ −
+ −
=>+ −
+ −
c[parent::b[parent::a]]+ −
+ −
-------------------------------------------------------------+ −
a/b/c/d+ −
+ −
=>+ −
+ −
d[parent::c[parent::b[parent::a]]]+ −
+ −
+ −
-------------------------------------------------------------+ −
/a/b/c/d+ −
+ −
=>+ −
+ −
d[parent::c[parent::b[parent::a[parent::document()]]]]+ −
+ −
This is handled specially; see | SLASH RelativePathPattern+ −
+ −
+ −
b/c rewrites to:+ −
TruthPredicate+ −
AxisStep self::element(c)+ −
AxisStep parent::element(b)+ −
+ −
For a/b/c we get:+ −
+ −
TruthPredicate+ −
TruthPredicate+ −
AxisStep self::element(c)+ −
AxisStep parent::element(b)+ −
AxisStep parent::element(a)+ −
+ −
But we want:+ −
+ −
TruthPredicate+ −
AxisStep child-or-top::element(c)+ −
TruthPredicate+ −
AxisStep parent::element(b)+ −
AxisStep parent::element(a)+ −
+ −
For a/b/c/d we get:+ −
+ −
TruthPredicate+ −
TruthPredicate+ −
TruthPredicate+ −
AxisStep self::element(d)+ −
AxisStep parent::element(c)+ −
AxisStep parent::element(b)+ −
AxisStep parent::element(a)+ −
+ −
For a/b/c/d we want:+ −
+ −
TruthPredicate+ −
AxisStep self::element(d)+ −
TruthPredicate+ −
AxisStep parent::element(c)+ −
TruthPredicate+ −
AxisStep parent::element(b)+ −
AxisStep parent::element(a)+ −
+ −
+ −
For /a/b we get:+ −
+ −
TruthPredicate+ −
TruthPredicate:+ −
AxisStep self::element(b)+ −
AxisStep parent::element(a)+ −
AxisStep parent::document()+ −
+ −
but we want:+ −
+ −
TruthPredicate+ −
AxisStep self::element(b)+ −
TruthPredicate: // PREDICATE+ −
AxisStep parent::element(a)+ −
AxisStep parent::document() // PREDICATE+ −
+ −
--------------------------------------------------------------+ −
For a/b/c we get:+ −
TruthPredicate+ −
AxisStep self::element(c)+ −
TruthPredicate+ −
parent::element(b)+ −
parent::element(a)+ −
+ −