@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

30 Jun at 16:40:00 GMT

Draft minutes published.

Issue #2169 closed #closed-2169

30 Jun at 16:27:24 GMT

Longest-token rule incorrectly produces `StringInterpolation` delimiter

Issue #2736 closed #closed-2736

30 Jun at 16:27:23 GMT

2169 Reformulate `StringInterpolation` to remove the `` `{ `` and `` }` `` literal terminals

Issue #2708 closed #closed-2708

30 Jun at 16:24:07 GMT

XPath, FLWOR, key/value keywords: map order

Issue #2732 closed #closed-2732

30 Jun at 16:24:06 GMT

2708 Obsolete references to maps being unordered

Issue #2536 closed #closed-2536

30 Jun at 16:21:07 GMT

EXPath modules: handling of default values

Issue #2711 closed #closed-2711

30 Jun at 16:21:06 GMT

2536 EXPath modules: handling of default values

Issue #2464 closed #closed-2464

30 Jun at 16:18:29 GMT

add method to use path()

Issue #2677 closed #closed-2677

30 Jun at 16:17:53 GMT

fn:transform statement about serialization-params and fn:serialize

Issue #2701 closed #closed-2701

30 Jun at 16:17:52 GMT

2677 Clarify effect of serialization-params on fn:transform

Issue #2741 created #created-2741

30 Jun at 13:07:57 GMT
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

29 Jun at 17:16:38 GMT
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:

  1. make all function arguments in the constructor function mandatory;
  2. reorder fields of built-in record types in the spec, by placing optional fields last;
  3. 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

29 Jun at 13:30:00 GMT

Draft agenda published.

Pull request #2739 created #created-2739

29 Jun at 12:09:40 GMT
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

29 Jun at 08:51:39 GMT
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

29 Jun at 08:41:27 GMT

strip-space option in fn:doc vs fn:document

Issue #2737 created #created-2737

29 Jun at 07:47:17 GMT
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

29 Jun at 07:02:28 GMT
2169 Reformulate `StringInterpolation` to remove the `` `{ `` and `` }` `` literal terminals

Reformulates StringInterpolation as proposed and discussed in #2169.

Closes #2169

Issue #2735 created #created-2735

28 Jun at 21:36:04 GMT
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

26 Jun at 21:50:55 GMT
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

26 Jun at 17:22:03 GMT
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

26 Jun at 13:30:35 GMT
2708 Obsolete references to maps being unordered

Fix #2708

Pull request #2731 created #created-2731

26 Jun at 11:43:42 GMT
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 fascicle element
  • expand the <?inject?> processing instruction

Issue #2730 closed #closed-2730

26 Jun at 11:36:46 GMT

2709 Make well formed subdocuments

Pull request #2730 created #created-2730

26 Jun at 11:34:36 GMT
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:

  1. shallow-skip the fascicle element
  2. expand the <?inject?> processing instruction

Issue #2728 closed #closed-2728

26 Jun at 09:53:57 GMT

test-pr

Issue #2729 created #created-2729

26 Jun at 09:36:04 GMT
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

26 Jun at 09:05:21 GMT

Another PR test; don't merge this one either

Issue #2725 closed #closed-2725

26 Jun at 09:05:18 GMT

Moar testing

Issue #2726 closed #closed-2726

26 Jun at 09:05:15 GMT

Why aren't actions running for my other tests?

See 5635 more statuses in yearly archives.