@qt4cg statuses
This page displays recent status updates about the QT4CG project.
The are also captured in an RSS feed.
By year: 2026, 2025, 2024, 2023, 2022, 2021, 2020
QT4 CG meeting 170 draft minutes #minutes-06-30
Draft minutes published.
Issue #2169 closed #closed-2169
Longest-token rule incorrectly produces `StringInterpolation` delimiter
Issue #2736 closed #closed-2736
2169 Reformulate `StringInterpolation` to remove the `` `{ `` and `` }` `` literal terminals
Issue #2708 closed #closed-2708
XPath, FLWOR, key/value keywords: map order
Issue #2732 closed #closed-2732
2708 Obsolete references to maps being unordered
Issue #2536 closed #closed-2536
EXPath modules: handling of default values
Issue #2711 closed #closed-2711
2536 EXPath modules: handling of default values
Issue #2464 closed #closed-2464
add method to use path()
Issue #2677 closed #closed-2677
fn:transform statement about serialization-params and fn:serialize
Issue #2701 closed #closed-2701
2677 Clarify effect of serialization-params on fn:transform
Issue #2741 created #created-2741
Record coercion, drop/keep empty entries?
#2566 says that optional fields in records are to be dropped (there is “no longer a distinction between absent values and empty values”). But the TypedRecordType coercion rule still adds an empty entry for every omitted field, so a coerced record keeps all its fields. The two seem to be mutually exclusive.
An example…
let $x as record(a as xs:integer, b as xs:string?) := { "a": 1 }
return map:size($x)
Coercion rule: 2 (with b added as ()); with #2566: 1.
…and the conflicting text snippets:
#2566 change note, Record Types:
Optional fields in records are dropped (in records, there is no longer a distinction between absent values and empty values).
Record-construction prose, same section:
The rules for the coercion operation ensure that the resulting record has one entry for every field in the corresponding record definition …
Coercion rules, TypedRecordType, the "Otherwise" clause:
Otherwise (if J contains no such entry), an entry whose key is the name of F and whose associated value is the empty sequence; a type error occurs if the empty sequence does not match the declared type of F.
Issue #2740 created #created-2740
Built-in records, constructor functions: optional fields
The record type definitions in the specs contain outdated extensible and required attributes, which I believe can be dropped:
<fos:record-type id="element-conversion-plan-record" extensible="false">
<fos:field name="layout" type="enum('empty', ...)" required="true">
...
</fos:field>
<fos:field name="child" type="xs:string?" required="false">
...
</fos:field>
<fos:field name="type" type="enum('integer', ...)" required="false">
...
</fos:field>
</fos:record-type>
But the more interesting question is the definition of the constructor functions: If the type of a record field indicates that the entry is optional, we could assign () as the default argument. However, this would require all subsequent parameters to be optional as well:
declare record fn:element-conversion-plan-record(
layout as enum('empty', ...),
child as xs:string? := (),
type as enum('integer', ...) (: ↯ :)
)
I can think of the following solutions:
- make all function arguments in the constructor function mandatory;
- reorder fields of built-in record types in the spec, by placing optional fields last;
- drop constructor functions for built-in record types from the spec.
Option 3 would be my favorite (unless we add at least one example in the prose how to benefit from the built-in functions. Otherwise, they will go wildly unnoticed anyway).
QT4 CG meeting 170 draft agenda #agenda-06-30
Draft agenda published.
Pull request #2739 created #created-2739
2738 XSLT - tree terminology
Fix #2738
Gently improves the introductory sections of the XSLT spec to better reflect the introduction of JTrees and JNodes.
It could do with a more radical overhaul but this is a step in the right direction.
Issue #2738 created #created-2738
XSLT Concepts: "tree", "document"
In the XSLT Concepts section and elsewhere, the terms "tree" and "document" are used without saying explicitly whether the terms include or exclude JTrees. Some of the statements that are made about trees are equally applicable to XTrees and JTrees, while others are specific to XTrees. Because the definitions are unclear, the use of these terms throughout the spec is also unclear. This extends to the XSLT Streaming spec.
Issue #2684 closed #closed-2684
strip-space option in fn:doc vs fn:document
Issue #2737 created #created-2737
context (or tunnel) parameters
I would like to propose an idea to introduce context parameters. The goal is to allow to pass parameter in a scope rather than globally or inside of a whole template.
The idea is like this:
<xsl:param name="my-var" as="xs:string" context="yes"/>
or even
<xsl:param name="my-var" as="xs:string" tunnel="yes"/>
...
<xsl:function name="t:my-function" as="xs:string">
...
<xsl:sequence select="$my-var"/>
</xsl:function>
....
<xsl:context>
<xsl:with-param name="my-var" select="'123'"/>
... do something, e.g.:
<xsl:sequence select="t:my-function(...)"/>
</xsl:context>
This feature will closely resemble what java and node have with async scoped variables. See https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/ScopedValue.html See https://nodejs.org/api/async_context.html
Pull request #2736 created #created-2736
2169 Reformulate `StringInterpolation` to remove the `` `{ `` and `` }` `` literal terminals
Reformulates StringInterpolation as proposed and discussed in #2169.
Closes #2169
Issue #2735 created #created-2735
JNodes: serialization
We should improve the representation of JNodes with the standard xml and json serialization methods. Keys are simply lost in the output, which is particularly troubling for newcomers:
(: query :)
<xml><city>Roma</city><name>Andrea</name></xml>/* ,
{ 'city': 'Roma', 'name': 'Andrea' }/*
(: result :)
<city>Roma</city>
<name>Andrea</name>
Roma
Andrea
My suggestion would be to output (non-root) JNodes as single-entry maps:
{ 'a': 1, 'b': 2 }/*
{ "a": 1 }
{ "b": 2 }
[ 'a', ('b', 'c') ]/*
[ 1: 'a' ]
[ 2: ('b', 'c') ]
An alternative for JNodes that result from arrays could be the representation as a single-member array (XML nodes don’t include indexes either):
[ 'a', ('b', 'c') ]/*
[ 'a' ]
[ ('b', 'c') ]
Pull request #2734 created #created-2734
2733 A step too far
Fix #2733
Changes the rules for the path operator E1/E2 where E1 selects JNode and E2 evaluates to an atomic value. This now performs context-based mapping, in the normal style for "/", except in the case where E2 is a literal or variable reference, in which case it expands to E1/child::{E2}.
Issue #2733 created #created-2733
A step too far: path expressions involving JNodes
It's really great to be able to write expressions like booklist/book[author='Mike']/price but there are usability traps. Consider this test case:
<test-case name="K2-Steps-40">
<description>
RHS of "/" operator can be any PostfixExpr.
LHS of dynamic function call is coerced from JNode to function(*)*
</description>
<created by="Michael Kay" on="2026-04-24"/>
<dependency type="spec" value="XP40+ XQ40+"/>
<test>{"A":1, "B":{"C":3, "D":4}}/B/.("C")</test>
<result>
<assert-eq>3</assert-eq>
</result>
</test-case>
The test is wrong: can you see why? The answer is that it successfully evaluates the final step .("C") to obtain the value 3, but it doesn't return 3 as the final result of the expression, rather it computes {"A":1, "B":{"C":3, "D":4}}/B/3 which returns nothing.
I'm coming to the view that this isn't acceptable. The semantics of G/A where G evaluates to a GNode and A evaluates to an atomic value are wildly different depending on whether G is an XNode or a JNode, and this is going to cause no end of confusion.
A possible solution is to allow the current semantics only in the case where the step is an NCName or a literal. If it's anthing else, for example a variable reference, you have to write G/child::{$i}. If A is any expression other than an NCName or a literal, then G/A works with JNodes the same as it does with XNodes - the "/" operator is essentially treated as "!".
We're still breaking referential transparency; writing 23 has a different effect from using a variable whose value is 23. That's essentially because "/" was never a pure operator in the first place, there have always been surprises in its semantics.
Pull request #2732 created #created-2732
2708 Obsolete references to maps being unordered
Fix #2708
Pull request #2731 created #created-2731
2709 Well-formed sub-documents (2nd attempt)
Fix #2709
(at least in part...)
In most of the parts making up the XPath and XQuery spec (with the exceptions of front and back matter), I have made the document well-formed by (a) adding a wrapper fascicle element where necessary (and declaring this in the DTD), and (b) eliminating external entity and character references that depend on the internal DTD subset.
The &language; entity reference is replaced by the processing instruction <?inject language?>
I have modified the assemble-specs stylesheet to:
- shallow-skip the
fascicleelement - expand the
<?inject?>processing instruction
Issue #2730 closed #closed-2730
2709 Make well formed subdocuments
Pull request #2730 created #created-2730
2709 Make well formed subdocuments
Fix #2709
(at least in part...)
In most of the parts making up the XPath and XQuery spec (with the exceptions of front and back matter), I have made the document well-formed by (a) adding a wrapper fascicle element where necessary (and declaring this in the DTD), and (b) eliminating external entity and character references that depend on the internal DTD subset.
The &language; entity reference is replaced by the processing instruction <?inject language?>
I have modified the assemble-specs stylesheet to:
- shallow-skip the
fascicleelement - expand the
<?inject?>processing instruction
Issue #2728 closed #closed-2728
test-pr
Issue #2729 created #created-2729
fn:replace: named capture groups
See https://github.com/qt4cg/qtspecs/pull/2717#issuecomment-4802675128:
In a replacement string, I suggest the syntax
$<group-name>. In a replacement function (which is new in 4.0), I suggest we make the second argument a map of groups rather than a sequence of groups.
Issue #2723 closed #closed-2723
Another PR test; don't merge this one either
Issue #2725 closed #closed-2725
Moar testing
Issue #2726 closed #closed-2726
Why aren't actions running for my other tests?
See 5635 more statuses in yearly archives.