@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 165 draft minutes #minutes-05-19
Draft minutes published.
Issue #2537 closed #closed-2537
Update records: `with { ... }`
Issue #1979 closed #closed-1979
Records: Type Safety
Issue #2566 closed #closed-2566
1979 Records with type annotations
Issue #2624 closed #closed-2624
Drop XPTY0019 and XPTY0020 in favour of XPTY0004
Issue #2627 closed #closed-2627
2624 Change error codes XPTY0019 and -0020 to XPTY0004
Issue #2598 closed #closed-2598
Add regex() function
Issue #2611 closed #closed-2611
2598 New function fn:regex
Issue #2640 closed #closed-2640
Remove space in function declaration between EQName & params
Issue #2642 created #created-2642
Allow xsl:analyze-string to use the results of fn:regex
We have a new function fn:regex() to return a reusable compiled regular expression, but there is currently no way to use this in xsl:analyze-string.
I suggest a new attribute regex="expression" on xsl:analyze-string; the required type of the (xpath) expression is fn:regex-record, that is, the type of the output of fn:regex(). If the new attribute is present then @pattern and @flags must be absent.
Issue #2641 created #created-2641
[Feature] Comments and parse-csv()
There is no standardization of comments in csv, but the inclusion of comment lines in csv documents is sufficiently widespread that Python pandas (https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html) and R (https://stat.ethz.ch/R-manual/R-devel/library/utils/html/read.table.html) cater for it. These are large communities that have substantial engagement over a long time with data in csv files.
Is it realistic to request a similar addition to the options parameter of XPath parse-csv()? The user can, to be sure, filter the lines before passing them to parse-csv(), but if it would not create an unacceptable burden for XPath 4.0 implementers to support it, wouldn't it be nicer to have it built in?
Issue #2619 closed #closed-2619
Formatting of options records
Issue #2629 closed #closed-2629
2619 Change formatting of options parameters
Issue #2597 closed #closed-2597
XSLT syntax scraps recurse too deeply
Issue #2630 closed #closed-2630
2597 Limit recursive depth in XSLT pattern exposition
QT4 CG meeting 165 draft agenda #agenda-05-19
Draft agenda published.
Pull request #2640 created #created-2640
Remove space in function declaration between EQName & params
While the space is legal, no other function declaration in the spec has one
Issue #2639 created #created-2639
XQuery 4.0: automated review, open questions
1. Switch comparison semantics (expressions.xml, ~lines 22943–22947)
Note text:
The comparisons are performed using the
fn:deep-equalfunction, after atomization.
Formal description (step 4 of the same section):
... compared using the contextually equal rules, with the default collation.
Issue: the note and the formal definition disagree on how case operands are compared. fn:deep-equal is a structural-equality function; "contextually equal" is the value-equality comparison used by eq. They give different results on e.g. atomized nodes vs. their string values.
Decision needed: which comparison rule is intended? Most likely the formal definition is correct ("contextually equal") and the note is leftover from an earlier draft.
2. Partial function application rewrite (expressions.xml, ~lines 11299–11300)
Current text:
the result of
F(X, Y, ...)isfor $FI in F return $FI(X, Y, ...).
This sentence appears in the partial-function-application section. The same rewrite, with the same wording, is also used in the dynamic-call section earlier (≈ line 10810). For ordinary dynamic calls it is correct.
Issue: when one or more of X, Y, … is a placeholder (?), the rewrite is wrong: the result is then a sequence of partially-applied functions, not the result of calling each function. The current text just defers to the dynamic-call rewrite, which does not handle placeholders.
Decision needed: either drop this paragraph and add a forward reference to the actual partial-application semantics, or rewrite it explicitly with ? placeholders.
3. for-each(., op('+')) example (expressions.xml, ~line 24108)
Pipeline example:
(1 to 4)
=> for-each(., op('+'))
=> for-each-pair(4 to 7, ., op('>'))
=> some(.)
described as "Doubles the values, then ...".
Issue: fn:for-each expects a unary function but op('+') produces a binary function. Either:
- the comment is wrong (this is not what doubles the values),
- the function name was meant to be different (e.g.
fn:fold-left), or - the operator was meant to be
op('*2')/fn($x) { $x + $x }/fn($x) { $x * 2 }.
Decision needed: what is this example supposed to demonstrate?
4. "no-namespace-rule" for pragma EQNames (expressions.xml, ~line 24697)
Current text:
The identifying EQName is expanded using the no-namespace-rule.
Issue: in context, an EQName can already be a prefixed or Q{…}name form, in which case the prefix / brace literal supplies the namespace. The no-namespace-rule only kicks in for an unprefixed NCName. The note immediately below this sentence already acknowledges this special case.
Decision needed: reword to "If the EQName is an unprefixed NCName, it is interpreted using the no-namespace-rule" (or equivalent), so the broader case is handled by the normal EQName expansion rules.
5. otherwise operator precedence (expressions.xml, ~lines 22823–22826)
Current text:
The
otherwiseoperator binds more tightly than comparison operators such as=, but less tightly than string concatenation (||) or arithmetic operators. The expression$a = @x otherwise @y + 1parses as$a = (@x otherwise (@y + 1)).
Issue: the precedence prose places otherwise between comparison and arithmetic operators, which is consistent with the example. However, the grouping (@x otherwise (@y + 1)) requires that + bind tighter than otherwise — which is what the prose says. So the example is consistent, but the wording "binds less tightly than … || or arithmetic operators" lumps || and + together as a single precedence level, which is incorrect — || is lower than + in the grammar.
Decision needed: clarify the precedence ordering; either split the bullet into separate clauses for string concatenation and arithmetic, or verify whether otherwise is intended to sit between || and arithmetic instead.
6. Ambiguous "otherwise" in finally clause (expressions.xml, ~line 23329)
Current text:
If it raises no error, it must yield the empty sequence; otherwise, a type error is raised XPTY0153.
Issue: "otherwise" is naturally read as "if it raises an error", but the intended condition is "if it raises no error but the result is not the empty sequence". The current wording is misleading; the immediately preceding sentence already covers the error-raising case.
Decision needed: reword to e.g. "If the finally clause completes without raising an error, its result must be the empty sequence; if it is not, a type error XPTY0153 is raised."
7. QName-literal example with unbound prefixes (expressions.xml, ~lines 15461–15466)
Example:
QName("http://example.com/ns1", "this:color")
eq QName("http://example.com/ns1", "that:color")
illustrating that QName equality ignores prefixes.
Issue: fn:QName requires the supplied prefix to be in the statically known namespaces of the call site (FONS0004). Without a declare namespace this = … and declare namespace that = … in the surrounding example context, this expression would raise an error, not return true.
Decision needed: either add the necessary namespace declarations to the example, or rephrase the demonstration in a form that does not depend on prefix resolution.
8. Deprecated namespace constructor in example (expressions.xml, ~line 18553)
Example:
namespace a { "http://a.example.com" }
Issue: the surrounding section (≈ 18353–18354, 18381–18384) introduces the namespace #a { ... } form and presents the unhashed form as deprecated when the name is not a reserved keyword. Mixing both forms in adjacent examples is inconsistent.
Decision needed: update the example to namespace #a { "http://a.example.com" }, or explicitly note that this is the deprecated form.
9. map:merge option example inconsistency (query-prolog.xml, ~lines 2241, 2271, 2319)
The same example block describes map:merge with three different option shapes:
- line 2241:
map:merge(({ "r": $r }, { "i": $i }))— no second argument - line 2271:
map:merge(..., { "retain-order": true() }) - line 2319 (formal): the default options map is
{ "duplicates": "use-first" }
Issue: the three are not obviously consistent. "retain-order" is not mentioned in the canonical option set elsewhere.
Decision needed: confirm the canonical option set in the current map:merge signature (xpath-functions-40) and update all three usages to match.
10. my:rectangle example method calls (query-prolog.xml, ~lines 2384–2387)
Example:
... =?=> expand(2)
... =?=> perimeter()
on an instance of the record type my:rectangle declared at 2363–2375.
Issue: the my:rectangle record declaration only defines area and resize. expand and perimeter are not declared. Either the record needs more method declarations, or the example calls need to use the declared methods.
Decision needed: which methods should the example demonstrate?
11. Atomic-set example clearly unfinished (query-prolog.xml, ~lines 2466, 2468, 2498)
The block already has an <ednote> (≈ 2514) noting the example is untested. Concrete defects spotted:
- 2466: trailing
*inrecord(...)suggests an extensible map type, but those were dropped from 4.0. - 2468:
declare %private variable DATA := "'_data'";is missing the$beforeDATA; later code references$DATA. - 2498: stray
"and missing,near{ keys($set?$DATA) }".
Decision needed: rewrite the whole example block once the intended semantics is clear, or remove the example.
12. errors.xml style consistency for DY/type-error pairs
A number of errors carry class="DY" type="type" (XPDY0002, XPDY0050, XQDY0102 — and a handful of inline <errorref> references that read "type error … XPDY0002"). The note at XPDY0002 explains the apparent inconsistency:
The error code is prefixed XPDY rather than XPTY for backwards compatibility reasons.
The same explanation is not attached to XPDY0050 and XQDY0102.
Decision needed: decide whether to add an analogous note to the other affected entries, or to drop the explanation from XPDY0002 (treating the prefix convention as common knowledge after the introduction).
13. doc.w3c-doctype-full = "Editor's Draft" vs. doc.stage (xpath.xml, xquery.xml, ~lines 28–30)
Current:
<!ENTITY doc.stage "WD"> <!-- xpath.xml -->
<!ENTITY doc.w3c-doctype "wd">
<!ENTITY doc.w3c-doctype-full "Editor's Draft">
<!ENTITY doc.stage "REC"> <!-- xquery.xml -->
<!ENTITY doc.w3c-doctype "rec">
<!ENTITY doc.w3c-doctype-full "Editor's Draft">
Issue: doc.stage says WD (xpath) or REC (xquery), but doc.w3c-doctype-full is "Editor's Draft" in both. "Editor's Draft" is not one of the W3C document stages listed in the comment header at the top of these files. The combinations look inconsistent in different ways for each file.
Decision needed: which combination is intended for the next publication step? Specifically, should doc.w3c-doctype-full track doc.stage (e.g. "W3C Working Draft" or "W3C Recommendation"), or is "Editor's Draft" a deliberate override used while the spec is on the editor's-draft pipeline?
14. Doubled !ENTITY definitions in xpath.xml and xquery.xml
Current (xpath.xml, similar pattern in xquery.xml):
<!ENTITY doc.publoc "https://qt4cg.org/specifications/&doc.shortname;/">
<!ENTITY doc.publoc "&w3c.tr;/&date.year;/&doc.w3c-designation;-&doc.date;/">
<!ENTITY doc.latestloc "&doc.publoc;">
<!ENTITY doc.latestloc "&w3c.tr;/&doc.shortname;/">
<!ENTITY doc.latestloc-tech "&doc.publoc;">
<!ENTITY doc.latestloc-tech "&w3c.tr;/&doc.generic-shortname;/">
Issue: each entity is declared twice in succession. In XML DTDs the first declaration wins; subsequent declarations for the same entity name are silently ignored. So either the duplication is dead code (the second definition never has any effect) or someone intended to toggle between alternatives by reordering — but the toggle is undocumented.
Decision needed: clarify the intent — either pick one definition for each entity, or add a comment explaining the toggle convention. (A common W3C pattern is to comment out the inactive alternative with <!-- ... -->.)
15. Namespace documents still on XQuery 3.1 (ns-features.xml, ns-local.xml, ns-xquery.xml)
All three files have:
- title and prose referring to "XQuery 3.1 ... Namespace Document"
- date entities pinned to 2017-03-21 (XQuery 3.1 REC date)
xq.spec.ver "31"and references tobibref ref="xquery-31-ref"- For
ns-features.xmlandns-xquery.xml: feature lists that still includeqf:static-typing(the static-typing feature was dropped in 4.0, conformance.xml 9–11) andqf:module/qfa:module(module processing is no longer optional in 4.0, conformance.xml 12–15). - For
ns-xquery.xmlline 96: "Those additional applications belong, by default, to ..." should likely be "annotations" (already flagged in the review).
Question: the namespace URIs themselves were published in XQuery 3.1 and presumably remain stable, so the file's identity (e.g. the 2011 date in the URI of xquery-features) shouldn't change. But there are two open editorial questions:
- Should the documents be re-versioned/re-dated for the 4.0 publication cycle, or kept frozen as 3.1 artefacts?
- If re-versioned, the static-typing and module entries need to be removed from the optional-features lists.
Decision needed: WG decision on the lifecycle of these namespace documents.
Pull request #2638 created #created-2638
2632-6: cross-cutting consistency
Pull request #2637 created #created-2637
2632-5: refresh stale 4.0 content
xpath.xml:
- customized-paragraph: "XPath version 4.1" -> "4.0"
- doc.w3c-prev-designation: was "REC-&doc.shortname;" which expands to "REC-xpath-40" (the current designation); fix to "REC-xpath-31"
- Bugzilla-key: "XPath31" -> "XPath40"
xquery.xml:
- customized-paragraph: still announced "XQuery version 3.1, a fully compatible extension of XQuery 3.0"; update to 4.0 / 3.1
- doc.w3c-prev-designation: as above, fix to "REC-xquery-31"
- Bugzilla-key: "XQuery31" -> "XQuery40"
- PR-entrance-criteria mentioned "human-readable syntax" and "XML syntax" (the XQueryX flavour). XQueryX is no longer maintained in 4.0 (introduction.xml 98-99); drop the syntax-specific criteria so the paragraph just requires two independent implementations of Minimal Conformance and of each optional feature
xpath-backwards-compat.xml:
- "In XPath 3.0 all these comparisons are type errors" -> "In XPath 4.0" (parallels the surrounding "not allowed in XPath 4.0" wording)
- drop the paragraph about "an XPath 4.0 implementation that provides the static typing feature": the static-typing feature was dropped from 4.0 (conformance.xml 9-11), so this paragraph no longer describes any conforming implementation
mime-type.xml:
- "specifies the media type for XQuery Version 1.0" -> "XQuery 4.0"
- "defines the language XQuery Version 1.0" -> "XQuery 4.0"
- allowed
xquery versionliteral list: add "4.0" alongside "1.0"/"3.0"/"3.1"
Issue: #2632
Pull request #2636 created #created-2636
2632-4: logic and semantics
query-prolog.xml:
- XQST0098 description: inverted polarity — "the properties identifying marker characters ... do identify distinct values" should be "do not"
- module-import termdef: cumulative not alternative ("or" -> "and") in the list of context components imported (in-scope variables, in-scope item types, ...). Same in the "If module A imports module B" paragraph.
- "enabling the definitions in the imported namespace" -> "imported schema" (the imported schema has no target namespace at this point)
- duplicate sentence "If the system log is in a different location, ..." in the context-value example removed; also "which is collection" -> "is a"
- library-module namespace constraint now applies only to public variables and functions (private names may be in any namespace since the 2025-04-24 changes — the matching change is already reflected at the specific rules for variables (1318) and functions (1785-1788))
expressions.xml:
- attribute axis: "empty unless the context node is an element" -> "empty unless the origin is an element" — matches the rest of the section which speaks of "origin"
- forward/reverse axis: mixed "origin" / "context node"; standardised on "origin" (the surrounding paragraphs use that term consistently)
- coercion table note: "unless either there is only one node" — drop the stranded "either"
- "The subtype relationship is not acyclic" -> "is not antisymmetric" (the following sentences describe an antisymmetry failure, not a cycle)
- subtype example: missing parens around the right-hand alternative "document-node(a|b) ⊆ (document-node(a) | document-node(b))", matching the equivalent examples for elements and attributes
- element-test examples list: "element(title|heading, xs:string) ⊆ element(*)" was listed twice (lines 7244 and 7247); drop the duplicate
- AnyFunctionType: "The keywords function and fn are synonymous" was both in prose (5793) and a note (5818); drop the redundant note
- fn:count#1 instance-of example: a stranded note about "fn($x as xs:int, $y as xs:int) as xs:int" referred to a 2-arity signature in a 1-arity example; remove
- attribute subtype rule: "attribute(Bn)" -> "attribute(B/n)" matching the surrounding var-style notation
- text node constructors: two near-identical notes about constructing zero-length text nodes; keep the more complete one
- try/catch: target expression / content expression were used interchangeably for the same thing; standardise on "content expression" (the defined term)
errors.xml:
- XQST0048 description aligned with the more specific rules: scope is public function/variable and item type, not any function/variable
back-matter.xml:
- numeric comparability list: xs:double was missing from "xs:integer, xs:decimal, or xs:float are mutually comparable"; the next sentence ("both operands are converted to xs:decimal ... sufficient precision for the xs:double value space") only made sense with xs:double included
- sort-functions list paragraph: opening "(" never closed before "are ultimately defined ..."
- dynamic-context table:
- "Current date and time" -> "Current dateTime" (matches the XQuery side and the dt-date-time term)
- "Available node collections" -> "Available collections" (matches the XQuery side and the function name "fn:collection")
Issue: #2632
Pull request #2635 created #created-2635
2632-3: typos and grammar
Pull request #2634 created #created-2634
2632-2: fix broken examples in expressions.xml
Pull request #2633 created #created-2633
2632-1: fix critical bugs and DTD-validity issues
Issue #2632 created #created-2632
XQuery 4.0: automated review
I have reviewed and revised the current XQuery 4.0 draft with the help of AI. To simplify the intellectual review of the PRs, I have split the fixes into multiple steps, for each of which I will create a PR:
- Critical bugs
- Broken examples
- Typos, grammar
- Logic, semantics
- Stale 4.0 content
- Cross-cutting consistency
Issue #2631 created #created-2631
Drop scan-left and scan-right
These functions have been in the spec for nearly two years but no-one has submitted any test cases or expressed any great enthusiasm for them. Unless someone wants them enough to write test cases, I propose that we drop them.
Pull request #2630 created #created-2630
2597 Limit recursive depth in XSLT pattern exposition
Fix #2597
Pull request #2629 created #created-2629
2619 Change formatting of options parameters
Changes the way options parameters are presented. The presentation as a record layout is abandoned, because options can no longer be described as record types (e.g., they are extensible). Field names are no longer followed by a question mark, because all options are optional, and this syntax for record types is being dropped anyway.
Fix #2619
Pull request #2628 created #created-2628
2617 Duration multiplied or divided by number
Fix #2617
QT4 CG meeting 164 draft minutes #minutes-05-12
Draft minutes published.
See 5447 more statuses in yearly archives.