<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet href="/xslt/atom.xsl" type="text/xsl"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xml:lang="EN-us"><title>Saxon diaries</title><subtitle>Michael Kay’s blog</subtitle><link href="https://blog.saxonica.com/mike/" rel="alternate" type="text/html"/><link href="https://blog.saxonica.com/atom/mike.xml" rel="self"/><id>https://blog.saxonica.com/mike/atom.xml</id><updated>2026-08-14T12:50:21.373780944Z</updated><author><name>Michael Kay</name></author><entry><title>Validating Linked Documents</title><link href="https://blog.saxonica.com/mike/2026/08/validating-linked-documents.html" rel="alternate" type="text/html"/><id>https://blog.saxonica.com/mike/2026/08/validating-linked-documents.html</id><published>2026-08-13T21:00:00Z</published><content type="xhtml" xml:base="https://blog.saxonica.com/mike/2026/08/validating-linked-documents.html"><div xmlns="http://www.w3.org/1999/xhtml">
        
        
        <p>A chance remark at Balisage 2026 (RIP) led me to consider the question:
        can you write an XSD schema to validate a linked set of XML documents, rather
        than just a single document?</p>
        
       
        
        <p>Here's a use case: the test suite for XQuery/XPath 4.0 consists of a catalog
        file, which lists 800 or so linked test sets. To make it more specific, the catalog
        contains many lines rather like this:</p>
        
        <p><code>&lt;test-set name="bin-shift" file="bin/shift.xml"/&gt; </code></p>
        
        <p>Both the top-level catalog and the
        individual test-set files are governed by XSD schemas. Currently we validate the
        collection of documents using an XQuery query along the lines of:</p>
        
        <p><code>//fots:test-set/@file ! (validate{doc(resolve-uri(., base-uri(..)))})</code></p>
        
        <p>And of course other solutions are possible, for example using XProc. But it occurred to
        me, can we write a schema for the catalog file that includes an XSD 1.1 assertion
        that invokes validation on the referenced test-set files? And can we use a different schema
        to validate the test-set files, different from the one we use for the catalog?</p>
        
        <p>I'll give you the answer first, before describing the journey to get there. I've made it work
        like this</p>
        
        <pre><code>
            
&lt;xs:annotation&gt;
   &lt;xs:appinfo&gt;
       &lt;saxon:param name="test-set-validator" 
                    select="xsd-validator(map{'schema-location': 'test-set-schema.xsd',
                                              'use-imported-schema': false(),
                                              'return-error-details': true()})"/&gt;
   &lt;/xs:appinfo&gt;
&lt;/xs:annotation&gt;
    
&lt;xs:element name="test-set"&gt;
  &lt;xs:complexType&gt;
    &lt;xs:complexContent&gt;
      &lt;xs:extension base="baseType"&gt;
        &lt;xs:attributeGroup ref="nameAttr"/&gt;
        &lt;xs:attributeGroup ref="fileAttr"/&gt;
        &lt;xs:assert test="
           let $doc := doc(resolve-uri(@file, base-uri(.)), 
                           {'xsd-validation':'skip'})
           let $validity := $test-set-validator($doc)
           return if ($validity?is-valid)
                  then true()
                  else (false(), `In {@file}: {$validity?error-details?message =&gt; string-join('. ')}`)"/&gt;
      &lt;/xs:extension&gt;
    &lt;/xs:complexContent&gt;                        
  &lt;/xs:complexType&gt;
&lt;/xs:element&gt;</code></pre>
        
        <p>This won't run out-of-the-box in Saxon 13.0: though most of the ingredients are present
        I had to make some tweaks to make it all hang together, which I'll describe as I go along.
        It should work as written in 13.1.</p>
        
        <p>Firstly, the <code>saxon:param</code> element has been available for quite a while as
        a Saxon extension. I'm using it here not to parameterize the validation, but rather to
        set up a global variable. The variable is the result of the 4.0 <code>xsd-validator</code>
        function: a new higher-order function that, given a schema, returns a function that can be
        used to validate instance documents against this schema. Putting this validator in a global
        variable means we only need to compile the schema for the test-set documents once.</p>
        
        <p>The expression in the <code>xs:assert/@test</code> attribute contains several features
        of note:</p>
        
        <ul>
            <li>Firstly, it calls the <code>doc()</code> function to load the test-set document referenced
            in the <code>@file</code> attribute. We're loading this document because we want to pass it
            to the validation function. The way <code>xsd-validator</code> works, you can only validate
            an already-built document tree. We want to do the validation using a different schema, so we
            can't do this within the <code>doc</code> function itself.</li>
            <li>Invoking the validator function (<code>let $validity := $test-set-validator($doc)</code>)
            returns a record containing potentially three things: a success/failure flag, a list of
            validation errors, and an annotated document representing the PSVI. We're not interested
            in the last part, so we didn't ask for it in the options to the <code>xsd:validator</code>
            call.</li>
            <li>We need to know which test-set documents are invalid, so it's helpful to have customized
            error message if the call on the validator function returns errors. There's an existing
            Saxon extension, <code>saxon:message</code>, which allows you to produce a custom
            message when an assertion fails, but unfortunately it's a fixed message, it can't be
            tailored to the actual data. So I invented a new mechanism. The XSD 1.1 specification says
            that if the result of the assertion has no effective boolean value, the assertion is taken
            as failing. So you can now return the sequence <code>(false(), "message")</code> from an
            assertion. This has no effective boolean value, so it is equivalent to returning false,
            but it also returns a diagnostic message explaining what is wrong. (The backtick expression
            is a string template, a new addition in XPath 4.0).</li>
            <li>XSD 1.1 expects assertions to use XPath 2.0 syntax but there is a Saxon attribute
            <code>saxon:extensions="any-xpath-version"</code> to relax this rule. (I found that this
            was only allowing 3.1 syntax, not 4.0, but this is now fixed).</li>
            <li>Finally, XSD 1.1 says that you can't call the <code>doc()</code> function from within
            an assertion. This is a security mechanism. So I added a new configuration option
            <code>--assertionsCanSeeResources:on</code> to bypass this mechanism: only set this
            option if you are using a trusted schema.</li>
        </ul>
        
        <p>So with Saxon 13.1, you will be able to invoke validation of a linked set of documents,
        using the same schema or different schemas, in a single call of the validation API.</p>
   
    </div></content></entry><entry><title>101 Fun things to do with QT4</title><link href="https://blog.saxonica.com/mike/2026/05/101-things-in-QT4.html" rel="alternate" type="text/html"/><id>https://blog.saxonica.com/mike/2026/05/101-things-in-QT4.html</id><published>2026-05-26T18:00:00Z</published><content type="xhtml" xml:base="https://blog.saxonica.com/mike/2026/05/101-things-in-QT4.html"><div xmlns="http://www.w3.org/1999/xhtml">
        
        
        <p>Here's a fun list of new features in the XPath 4.0, XQuery 4.0, and XSLT 4.0,
        that are available to play with in Saxon 13.</p>
        
        <ol>
            <!-- 1 to 10 -->
            <li>
                <p>Select an attribute, using a default value if absent</p>
                <p><code>@discount otherwise 0</code></p>
            </li>
            <li>
                <p>Use a conditional with no else branch</p>
                <p><code>if (@discount) { " (reduced!)" }</code></p>
            </li>
            <li>
                <p>Shorten <code>function</code> to <code>fn</code></p>
                <p><code>for-each(//employee, fn($e){$e/@ssn})</code></p>
            </li>
            <li>
                <p>Use the context item to simplify arity-1 functions</p>
                <p><code>for-each(//employee, fn{@ssn})</code></p>
            </li>
            <li>
                <p>Drop the <code>map</code> keyword from map constructors</p>
                <p><code>let $map := {'x':1, 'y':2}</code></p>
            </li>
            <li>
                <p>Include conditional entries in a map constructor</p>
                <p><code>{'x': +@x, 'y': +@y, if (@z) {{'z': +@z}}} </code></p>
            </li>
            <li>
                <p>Include multiple entries in a map constructor</p>
                <p><code>{//data ! {@key : string(@value)}}</code></p>
            </li>
            <li>
                <p>Build a map from a sequence</p>
                <p><code>map:build(//employee, fn{@ssn})</code></p>
            </li>
            <li>
                <p>Select a range of entries from a sequence</p>
                <p><code>$input[1 to 5]</code></p>
            </li>
            <li>
                <p>Start talking about <i>atomic items</i> rather than <i>atomic values</i></p>
            </li>
            
            <!-- 11 to 20 -->
            <li>
                <p>Use QName literals</p>
                <p><code>node-name($node) = #xml:space</code></p>
            </li>
            <li>
                <p>Use underscore in numeric literals</p>
                <p><code>let $million := 1_000_000</code></p>
            </li>
            <li>
                <p>Use hex literals</p>
                <p><code>let $mask := 0xffff</code></p>
            </li>
            <li>
                <p>Use alternative names in an element test</p>
                <p><code>//element(chapter|appendix)</code></p>
            </li>
            <li>
                <p>Declare namespaces in XPath</p>
                <p><code>declare namespace p = "http:/my.ns"; //p:table</code></p>
            </li>
            <li>
                <p>Declare a default namespace in XPath</p>
                <p><code>declare default element namespace "http:/my.ns"; //table</code></p>
            </li>
            <li>
                <p>Use <code>##any</code> to match elements by local name, ignoring namespace</p>
                <p><code>declare default element namespace "##any"; //table</code></p>
            </li>
            <li>
                <p>Use string templates</p>
                <p><code>`{$firstname} {$lastname}`</code></p>
            </li>
            <li>
                <p>Use × and ÷ for multiplication and division</p>
                <p><code>@price × 1.2</code></p>
            </li>
            <li>
                <p>Convert untyped atomic values implicitly to decimal where appropriate</p>
                <p><code>&lt;a&gt;1.1&lt;/a&gt; = 1.1</code></p>
            </li>
            
            <!-- 21 to 30 -->
            <li>
                <p>Write <code>&lt;&lt;</code> and <code>&gt;&gt;</code> as <code>precedes</code> and <code>follows</code></p>
                <p><code>para[. precedes $first-heading]</code></p>
            </li>
            <li>
                <p>Compare nodes using <code>is-not</code></p>
                <p><code>*[. is-not $first-heading]</code></p>
            </li>
            <li>
                <p>Use the <code>=!&gt;</code> operator to apply a function to all items in a sequence</p>
                <p><code>tokenize($str) =!&gt; upper-case()</code></p>
            </li>
            <li>
                <p>Use the pipeline operator <code>-&gt;</code> to set the context item for an expression</p>
                <p><code>$employee -&gt; `First name: {@first} Last name: {@last}`</code></p>
            </li>
            <li>
                <p>Use a multi-character representation of "percent" in a decimal format</p>
                <p><code>percent = "%:pc"</code></p>
            </li>
            <li>
                <p>Start talking about <i>coercion rules</i> rather than <i>function conversion rules</i></p>
            </li>
            <li>
                <p>Take advantage of down-casting in the coercion rules:</p>
                <p><code>declare function my:f($x as xs:positiveInteger){$x + 1}; my:f(3)</code></p>
            </li>
            <li>
                <p>Check that you always have a space after <code>"{#"</code> in a pragma</p>
                <p><code>{# saxon:extension xxx #}</code></p>
            </li>
            <li>
                <p>Take advantage of coercion in variable declarations</p>
                <p><code>let $x as xs:decimal := @price</code></p>
            </li>
            <li>
                <p>Declare functions with optional parameters</p>
                <p><code>declare function my:f($x as xs:integer := 0)</code></p>
            </li>
            
            <!-- 31 to 40 -->
            <li>
                <p>Use keywords in function calls</p>
                <p><code>substring($value, start := 3)</code></p>
            </li>
            <li>
                <p>Declare functions with no namespace prefix</p>
                <p><code>declare function increment($x) {$x+1}; increment(42)</code></p>
            </li>
            <li>
                <p>Serialize output as canonical XML</p>
                <p><code>serialize($output, {'method': 'xml', canonical': true()})</code></p>
            </li>
            <li>
                <p>Take advantage of the functions in the <b>bin</b> and <b>file</b> namespaces.
                Previously defined in EXPath, these are now integrated into the specs.</p>
            </li>
            <li>
                <p>Watch out for decimal=double comparisons. These are now compared as decimals, not as doubles</p>
                <p><code>1.1e0 != 1.1</code></p>
            </li>
            <li>
                <p>Convert arbitrary XML to JSON using the element-to-map function</p>
                <p><code>element-to-map(doc('books.xml')/*)</code></p>
            </li>
            <li>
                <p>Process CSV input files using the new <code>csv-doc</code> and <code>parse-csv</code> functions</p>
                <p><code>csv-doc('data.csv')</code></p>
            </li>
            <li>
                <p>Process HTML input files</p>
                <p><code>parse-html('index.html')</code></p>
            </li>
            <li>
                <p>Use higher-order functions knowing they will be there in all implementations. Higher-order
                functions are no longer an optional feature.</p>
            </li>
            <li>
                <p>Use the second argument of callback functions to get the position of an item in a sequence</p>
                <p><code>filter($input, fn{$item, $pos){$pos gt 5})</code></p>
            </li>
            
            <!-- 41 to 50 -->
            <li>
                <p>Get the last item of a sequence using foot()</p>
                <p><code>foot($input)</code></p>
            </li>
            <li>
                <p>Get selected items in a sequence using slice()</p>
                <p><code>slice($in, start := 5, end := 2, step := -2)</code></p>
            </li>
            <li>
                <p>Use the <code>deep-equal()</code> function with options to control the comparison</p>
                <p><code>deep-equal($p1, $p2, {'whitespace': 'normalize'})</code></p>
            </li>
            <li>
                <p>Use the <code>all-different()</code> function to check uniqueness of values</p>
                <p><code>all-different(//test-case/@name)</code></p>
            </li>
            <li>
                <p>Use the <code>highest()</code> and <code>lowest()</code> functions to find
                the items with the minimum or maximum value of some property</p>
                <p><code>highest(//employee, fn{@salary})</code></p>
            </li>
            <li>
                <p>Use the <code>index-where()</code> function to find the positions of all
                items with some property</p>
                <p><code>index-where(*, fn{exists(self::h2)})</code></p>
            </li>
            <li>
                <p>Use the <code>partition()</code> function to perform positional grouping</p>
                <p><code>partition(*, fn($group, $next){exists($next[self::h2])})</code></p>
            </li>
            <li>
                <p>Use the <code>sort-by()</code> function to sort a sequence using multiple sort keys</p>
                <p><code>sort-by(//person, ({'key': fn{@last}}, {'key': fn{@date-of-birth}, 'order': 'descending'}))</code></p>
            </li>
            <li>
                <p>Use the <code>sort-with()</code> function to sort using a comparator</p>
                <p><code>sort-with($input, compare#2), </code></p>
            </li>
            <li>
                <p>Use <code>take-while</code> to select items from a sequence until some condition is false</p>
                <p><code>take-while(*, fn{not(self::h2)})</code></p>
            </li>
            
            <!-- 51 to 60 -->
            <li>
                <p>Use <code>is-NaN</code> to check whether an input item is NaN</p>
                <p><code>*[not(is-NaN(.))]</code></p>
            </li>
            <li>
                <p>Use <code>round()</code> with an explicit rounding mode</p>
                <p><code>round($value, precision := '2', mode := 'half-toward-zero')</code></p>
            </li>
            <li>
                <p>Read integers in hexadecimal notation</p>
                <p><code>parse-integer("feff", 16)</code></p>
            </li>
            <li>
                <p>Format integers in hexadecimal notation</p>
                <p><code>format-integer($value, '16^xxxxxxxx')</code></p>
            </li>
            <li>
                <p>Supply inline options to <code>format-number()</code></p>
                <p><code>format-number($value, {'decimal-separator': ',', 'grouping-separator': '.'})</code></p>
            </li>
            <li>
                <p>Use new mathematical functions <code>math:e()</code>, <code>math:sinh()</code>, etc.</p>
                <p><code>math:cosh(1)</code></p>
            </li>
            <li>
                <p>Use the new collation for Unicode case-blind comparison</p>
                <p><code>compare($a, $b, "http://www.w3.org/2005/xpath-functions/collation/unicode-case-insensitive")</code></p>
            </li>
            <li>
                <p>Construct a collation with desired properties</p>
                <p><code>compare($a, $b, collation({'lang': 'se', 'numeric': true()}))</code></p>
            </li>
            <li>
                <p>Get the character with a given codepoint</p>
                <p><code>char(0xA0)</code></p>
            </li>
            <li>
                <p>Get the character with a given HTML entity name</p>
                <p><code>char("nbsp")</code></p>
            </li>
            
            <!-- 61 to 70 -->
            <li>
                <p>Get all the characters in a string</p>
                <p><code>characters($input)</code></p>
            </li>
            <li>
                <p>Use lookahead and lookbehind in regular expressions</p>
                <p><code>matches($input, "Chapter(?=\s+[1-9])")</code></p>
            </li>
            <li>
                <p>Match word boundaries in a string</p>
                <p><code>matches($input, "\bthe\b")</code></p>
            </li>
            <li>
                <p>Compute replacement values for matching substrings</p>
                <p><code>replace($input, "(0-9)+", fn{.+1})</code></p>
            </li>
            <li>
                <p>Split a URI into its parts, and recombine them</p>
                <p><code>parse-uri(@href) =&gt; map:put('scheme', 'https') =&gt; build-uri()</code></p>
            </li>
            <li>
                <p>Build a date or time from its components</p>
                <p><code>build-dateTime({'year': $year, 'month': $month, 'day': $day})</code></p>
            </li>
            <li>
                <p>Get the civil timezone offset at a given time and place</p>
                <p><code>civil-timezone(current-dateTime(), 'Europe/London')</code></p>
            </li>
            <li>
                <p>Use <code>@then</code> and <code>@else</code> on <code>xsl:if</code></p>
                <p><code>&lt;xsl:if test="@type=1" then="@full-name" else="@abbreviation"/&gt;</code></p>
            </li>
            <li>
                <p>Use <code>@select</code> on <code>xsl:when</code> and <code>xsl:otherwise</code></p>
                <p><code>&lt;xsl:choose&gt;&lt;xsl:when test="@type=1" select="'gasket'"/&gt;&lt;/xsl:choose&gt;</code></p>
            </li>
            <li>
                <p>Select options using the new <code>xsl:switch</code> instruction</p>
                <p><code>&lt;xsl:switch select="@type"&gt;&lt;xsl:when test="1" select="'gasket'"/&gt;&lt;/xsl:switch&gt;</code></p>
            </li>
            
            <!-- 71 to 80 -->
            <li>
                <p>Provide default values for XSLT function parameters</p>
                <p><code>&lt;xsl:param name="options" as="map(*)" required="no" select="{}"/&gt;</code></p>
            </li>
            <li>
                <p>Use XSLT functions in no namespace</p>
                <p><code>&lt;xsl:function name="f"&gt;...&lt;/xsl:function&gt;</code></p>
            </li>
            <li>
                <p>Use <code>xsl:text</code> in preference to <code>xsl:value-of</code></p>
                <p><code>&lt;xsl:text&gt;{position()} of {last()}&lt;/xsl:text&gt;</code></p>
            </li>
            <li>
                <p>Construct CDATA sections selectively in serialized output</p>
                <p><code>&lt;xsl:text cdata="true" select="$example"/&gt;</code></p>
            </li>
            <li>
                <p>Use capturing accumulators to capture a snapshot of an element as an accumulator value</p>
                <p><code>&lt;xsl:accumulator-rule match="heading" phase="end" capture="yes" select="."/&gt;</code></p>
            </li>
            <li>
                <p>Use explicit options to control XML parsing in the <code>doc()</code> and <code>document()</code> functions</p>
                <p><code>doc("input.xml", {'dtd-validation': true()})</code></p>
            </li>
            <li>
                <p>Build arrays in XSLT using <code>xsl:array</code> and <code>xsl:array-member</code></p>
                <p><code>&lt;xsl:array select="1 to 5"/&gt;</code></p>
            </li>
            <li>
                <p>Control the handling of duplicate keys in <code>xsl:map</code> with the new <code>duplicates</code> option</p>
                <p><code>&lt;xsl:map duplicates="'use-last'"&gt;...&lt;/xsl:map&gt;</code></p>
            </li>
            <li>
                <p>Stop JSON output displaying <code>/</code> as <code>\/</code></p>
                <p><code>escape-solidus="no"</code></p>
            </li>
            <li>
                <p>Serialize a sequence of maps in json-lines format (one JSON object per line, newline separated)</p>
                <p><code>json-lines="yes"</code></p>
            </li>
            
            <!-- 81 to 90 -->
            <li>
                <p>Use different XSD schemas for validating the input and output of a transformation</p>
                <p><code>&lt;xsl:import-schema role="output"/&gt;, &lt;xsl:result-document schema-role="output"/&gt;</code></p>
            </li>
            <li>
                <p>Write all the template rules for a given mode as children of the <code>xsl:mode</code> element</p>
                <p><code>&lt;xsl:mode name="M"&gt;&lt;xsl:template match="A"/&gt;&lt;/xsl:mode&gt;</code></p>
            </li>
            <li>
                <p>In an XSLT module, link to the main module to help IDEs locate all the variable and function declarations</p>
                <p><code>&lt;xsl:transform main-module="main.xsl"&gt;...&lt;/xsl:transform&gt;</code></p>
            </li>
            <li>
                <p>Use <code>xsl:note</code> elements for structured XSLT documentation</p>
                <p><code>&lt;xsl:note&gt;This is a comment&lt;/xsl:note&gt;</code></p>
            </li>
            <li>
                <p>Use <code>fixed-namespaces</code> to reduce the amount of boilerplate on the <code>xsl:transform</code> element</p>
                <p><code>&lt;xsl:transform fixed-namespaces="#standard"&gt;...&lt;/xsl:transform&gt;</code></p>
            </li>
            <li>
                <p>Take advantage of new features for simplified stylesheets. The outermost element
                can now be any instruction, for example <code>xsl:result-document</code> or <code>xsl:map</code>.</p>    
            </li>
            <li>
                <p>Make unprefixed name tests match elements in any namespace</p>
                <p><code>xpath-default-namespace="##any"</code></p>
            </li>
            <li>
                <p>Declare named item types</p>
                <p><code>&lt;xsl:item-type name="binary" select="(xs:hexBinary | xs:base64Binary)"/&gt;</code></p>
            </li>
            <li>
                <p>Use types in match patterns</p>
                <p><code>match="~map(xs:string, xs:integer)</code></p>
            </li>
            <li>
                <p>Use the <code>separator</code> attribute in <code>xsl:for-each</code></p>
                <p><code>&lt;xsl:for-each select="$input" separator=","&gt;...&lt;/xsl:for-each&gt;</code></p>
            </li>
            
            <!-- 91 to 100 -->
            <li>
                <p>Use record types to declare maps with statically known fields</p>
                <p><code>as record(first as xs:string, middle as xs:string*, last as xs:string)</code></p>
            </li>
            <li>
                <p>Declare function parameters using choice types</p>
                <p><code>as (xs:date | xs:time | xs:dateTime)</code></p>
            </li>
            <li>
                <p>Declare function parameters using enumeration types</p>
                <p><code>as enum("red", "green", "blue")</code></p>
            </li>
            <li>
                <p>Use path expressions to navigate trees of maps and arrays (JNodes)</p>
                <p><code>$map/authors/*[1]/name/first ! string()</code></p>
            </li>
            <li>
                <p>Iterate over arrays with an enhanced FLWOR expression</p>
                <p><code>for member $m in $array ... return count($m)</code></p>
            </li>
            <li>
                <p>Iterate over maps with an enhanced FLWOR expression</p>
                <p><code>for key $key value $value in $map return `{$key} = {$value}`</code></p>
            </li>
            <li>
                <p>Use computed node constructors in XPath</p>
                <p><code>attribute #xlink:href {$target}</code></p>
            </li>
            <li>
                <p>Use enhanced <code>for</code> and <code>let</code> expressions in XPath</p>
                <p><code>for $x as xs:string at $pos in $X let $r := string-length($x) + $pos return $r + 1</code></p>
            </li>
            <li>
                <p>Use destructuring map assignments</p>
                <p><code>let {$height, $width} := $rectangle return $height × $width</code></p>
            </li>
            <li>
                <p>Use destructuring array assignments</p>
                <p><code>let [$first, $second, $third] := $array return ($first, $second, $third)</code></p>
            </li>
            
            <!-- 101 -->
            <li>
                <p>Read the specifications at <a href="http://qt4cg.org/">http://qt4cg.org/</a>,
                and provide feedback at <a href="https://github.com/qt4cg/qtspecs">https://github.com/qt4cg/qtspecs</a></p>
            </li>
        </ol>
   
    </div></content></entry><entry><title>Ordered Maps and JNodes</title><link href="https://blog.saxonica.com/mike/2025/08/implementing-jnodes.html" rel="alternate" type="text/html"/><id>https://blog.saxonica.com/mike/2025/08/implementing-jnodes.html</id><published>2025-08-19T09:00:00Z</published><content type="xhtml" xml:base="https://blog.saxonica.com/mike/2025/08/implementing-jnodes.html"><div xmlns="http://www.w3.org/1999/xhtml">
        <h1>Ordered Maps and JNodes</h1>
        
        <p>Since I last wrote about <a href="https://blog.saxonica.com/mike/2024/12/ordered-maps.html">ordered maps</a>,
        the XPath 4.0 specifications have now introduced the idea of JNodes, which adds a new set of 
        requirements to the specification.</p>
        
        <p>I wrote about JNodes in <a href="https://www.balisage.net/Proceedings/vol30/html/Kay01/BalisageVol30-Kay01.html">my paper at Balisage 2025</a>, 
        and I won't repeat the introduction here. Suffice it to say that a JNode can wrap a specific entry in an XDM
        map, and it allows you (among other things) to:</p>
        
        <ol>
            <li>Establish which of two entries in the same map comes first in document order (or equivalently,
            in map order);</li>
            <li>Get the preceding or following siblings of a map entry (the entries that precede it or follow it 
                in map order).</li>
        </ol>
        
        <p>The prototype implementation of JNodes that I demonstrated at Balisage included support for these
        operations, but the implementation would be hopelessly inefficient in production. The current implementation
        of ordered maps on the Saxon 13 development branch uses the <code>LinkedHashMap</code> implementation
            from the VAVR library, and this doesn't have anything that would support either of these operations.</p>
        
        <p>I'm therefore proposing to use a home-grown map implementation as described below.</p>
        
        <p>First note that <code>map:put</code> and <code>map:remove</code> operations are rare, and it's OK
        to have a map implementation that allows the map to be constructed by a mutable builder class in one phase of operation,
        and thereafter to be read-only. If a <code>map:put</code> or <code>map:remove</code> operation is attempted,
        we can rebuild the map using a different (immutable | persistent | functional) data structure. 
        So let's first consider a structure that 
        doesn't support <code>map:put</code> and <code>map:remove</code> operations directly. I'm calling this
        a <code>FixedMap</code>.</p>
        
        <p>A <code>FixedMap</code> is underpinned by three Java structures:</p>
        
        <ul>
            <li><code>keys</code>: An array of keys: type <code>AtomicValue[]</code>.</li>
            <li><code>values</code>: An array of values: type <code>GroundedValue[]</code>.</li>
            <li><code>index</code>: A map from atomic match keys to integers: type <code>Map&lt;AtomicMatchKey, Integer&gt;&gt;</code>.
            Note that this map doesn't need to be ordered. The class <code>AtomicMatchKey</code> is a surrogate
            for an XDM atomic value whose Java <code>equals()</code> method respects the XDM equality
            semantics: for example, if the key is an <code>xs:string</code> then the <code>AtomicMatchKey</code>
            is an instance of Saxon's <code>UnicodeString</code> class.</li>
        </ul>
        
        <p>The basic operations on XDM maps are simply and efficiently implemented as follows:</p>
        
        <ul>
            <li>Get the value corresponding to a given key: set <code>i = index.get(key)</code>;
                return if <code>i == null</code> then <code>null</code> else <code>values[i]</code>.</li>
            <li>Get all keys in map order: iterate over <code>keys</code>.</li>
            <li>Get all values in map order: iterate over <code>values</code>.</li>
        </ul>
        
        <p>The new operations required to support JNode navigation can also be efficiently implemented:</p>
        
        <ul>
            <li>Determine which of two entries with keys <code>X</code> and <code>Y</code> is first in document
                order: compare <code>index.get(X)</code> with <code>index.get(Y)</code> (an integer comparison).</li>
            <li>Get preceding or following siblings of an entry with key <code>X</code>: find <code>index.get(X)</code>
            and then iterate forwards or backwards in the <code>keys</code> and <code>values</code> arrays
            from this integer offset.</li>
        </ul>
        
        <p>All very straightforward. Now, what about <code>map:put</code> and <code>map:remove</code>?</p>
        
        <p>When one of these operations occurs, I propose to copy the <code>FixedMap</code> to an
        <code>ExtensibleMap</code>. This will have a very similar structure to the <code>FixedMap</code>, except
        that:</p>
        
        <ul>
            <li>The arrays of keys and values are replaced by immutable lists of keys and values. 
            I propose to implement these immutable lists using the existing Saxon class <code>ZenoChain</code>.
            This is described in a <a href="https://blog.saxonica.com/mike/2021/03/zeno_chains.html">previous blog</a>.    
            This uses the same logic as the <code>ZenoString</code> which I introduced in 
            <a href="https://www.balisage.net/Proceedings/vol26/html/Kay01/BalisageVol26-Kay01.html">a 2021 Balisage paper.</a>
            It provides efficient support for getting an entry at a particular integer offset, and for appending
            individual entries at the end of the list: therefore for <code>map:get</code> and <code>map:put</code>.</li>
            <li>The map from <code>AtomicMatchKey</code> to <code>Integer</code> is replaced by an immutable map.
            There are plenty of implementations available (we could revert to the Michael Froh implementation
            used in earlier Saxon releases), because there is no need for this structure to support ordering.</li>
        </ul>
        
        <p>The design relies on the fact that adding or removing entries to the map does not change the integer
        offset of existing entries. That's fine for <code>map:put</code>, which always puts new entries at the end
        (in terms of map ordering). To support <code>map:remove</code>, I propose to keep a separate list holding
        the integer offsets of map entries that have been removed; a traversal of the map keys or arrays needs
        to check this list and skip an entry if it is present. When the number of removed entries exceeds some
        threshold (a rare event) we can rebuild the map from scratch.</p>
        
        <p>The new design looks as if all the main operations perform in constant or logarithmic time, with traversal
        of the map in linear time; and it seems to be reasonably economical in terms of memory usage.</p>
        
        <p>The design allows the use of an optimization whereby the index (from atomic match keys to integer offsets)
        is built lazily, the first time <code>map:get</code> is called. This is useful when processing JSON, because
        it's likely that many maps constructed during JSON parsing will either be copied unchanged to the
        transformation output, or will never be referenced at all, so the work needed to construct an index can be
        saved (it's still necessary to check for duplicate keys, but this can be done cheaply with a simple Bloom
        filter).</p>
        
        <p>We currently have an optimized implementation of maps for cases where all the keys are known in advance
        to be instances of <code>xs:string</code>. This can potentially save a bit of space because in place
            of the <code>StringValue</code> representing each string-valued key, we can simply store the underlying
            <code>UnicodeString</code>. This saves holding the wrapper object and the type annotation, which can
            be significant in the case of very large maps.</p>
        
        <p>One of the benefits of this design is that it reduces our dependencies on third-party code, which in
        turn simplifies porting Saxon across different platforms, and transpiling to C# for the .NET platform.
        In the current Saxon 13 code base, we're not only dependent on the VAVR library, but we're actually
        dependent on a fork of that library that uses a different implentation of linked hash maps, to avoid
        a <a href="https://github.com/vavr-io/vavr/issues/2727">performance bug</a>.</p>
        
        
  
 
   
    </div></content></entry><entry><title>Ordered Maps</title><link href="https://blog.saxonica.com/mike/2024/12/ordered-maps.html" rel="alternate" type="text/html"/><id>https://blog.saxonica.com/mike/2024/12/ordered-maps.html</id><published>2024-12-29T09:00:00Z</published><content type="xhtml" xml:base="https://blog.saxonica.com/mike/2024/12/ordered-maps.html"><div xmlns="http://www.w3.org/1999/xhtml">
        
        
        <p>There's been a lot of discussion recently in the QT4 community group about introducing
        ordered maps: that is, maps in which there is a defined and predictable ordering of entries,
        typically "last-in, last-out" where the most recently added entry always appears at the end.
        The main motivation for this is that JSON is designed (like XML) to be human-readable, but
        JSON content in which the entries appear in random order is anything but: if a phone bill
        contains a name, address, account number, a summary of charges, and an itemized list of calls,
        then you don't want the phone number appearing in the middle, sandwiched between the
        list of calls and the list of charges. Currently when data is serialized as JSON, we provide
        an option to indent it for readability, but indentation isn't going to make the data readable if
        it's in random order.</p>
        
        <p>Retaining order is particularly useful for visual inspection of changes: if you write code that
        modifies one entry in a JSON document, you want to satisfy yourself that the transformation
        did exactly what you expected, and the best way to convince yourself is by placing the
        input and output side-by-side and comparing them visually.</p>
        
        <p>There seems to be consensus that support for ordered maps, at least in some circumstances,
        is desirable. There is debate about whether all maps should be ordered, and about whether
        ordering should be the default, and about whether ordering should be supported if a map
        is built incrementally using <code>map:put</code> operations. The answer to those questions
        depends at least in part on understanding how great the overhead is in retaining order
        in maps: if the overhead is negligible, then we might as well make all maps ordered.</p>
        
        <p>Normally I'm the first to argue that the language specification should not be driven
        by performance concerns: we should design a clean language and leave implementors to
        worry about how to implement it efficiently. But in this case, if we're making a change
        to the language semantics that affects users whether they want the feature or not, I think
        we need to understand clearly whether we are asking users to pay a performance price.</p>
        
        <p>Both JavaScript (from ES2015) and Python (from 3.7) have moved 
        in the direction of making all maps (objects/dictionaries) ordered, so we wouldn't 
        be on our own in doing this. However, JavaScript objects and Python dictionaries
        are mutable, whereas XDM maps are functionally persistent (adding an entry
        creates a new map, leaving the original unchanged), so the performance
        constraints are somewhat different.</p>
        
        <p>So let's look now at how Saxon implements maps.</p>
        
        <p>In SaxonJ 12.x there are two main implementations (ignoring special cases such as empty
        maps and singleton maps). The default implementation is in the class 
        <code>net.sf.saxon.ma.map.HashTrieMap</code>, and this is built using an open source
        implementation of immutable hash tries written by Michael Froh; it has been in the
        product since 9.6. In SaxonCS 12.x we replace this with the functionally equivalent Microsoft 
        class <code>System.Collections.Immutable.ImmutableDictionary</code>. Both these library
        implementations are unordered.</p>
        
        <p>There is a minor tweak that complicates the implementation. In an ideal world,
        we would create an underlying map of type <code>Map&lt;AtomicValue, GroundedValue&gt;</code>,
        where <code>AtomicValue</code> is the Saxon class used to hold all atomic values,
        and <code>GroundedValue</code> is the Saxon class used to hold all sequences other than
        those that are lazily-evaluated. However, <code>AtomicValue.equals()</code> does
        not implement the equality semantics defined by XDM for comparing map keys. This
        is because XPath has different rules for equality comparisons in different circumstances.
        The Microsoft <code>ImmutableDictionary</code> can take a custom <code>KeyComparer</code>
        parameter, which would solve this problem, but there is no equivalent in the Froh
        library that we use in SaxonJ. So instead we implement an underlying map of type
        <code>Map&lt;AtomicMatchKey, Tuple&lt;AtomicValue, GroundedValue&gt;&gt;</code>, where
        <code>AtomicMatchKey</code> is a value derived from the <code>AtomicValue</code>
        that has the correct equality semantics. We need to hold the <code>AtomicValue</code>
        because in general two atomic values can have the same <code>AtomicMatchKey</code>
        (for example this is the case when the keys are a mix of different numeric types):
        and the XPath functionality for maps requires the original key value (including
        its type annotation) to be retained.</p>
        
        <p>The second implementation of maps found in SaxonJ and SaxonCS is the class
        <code>net.sf.saxon.ma.map.DictionaryMap</code>. This is implemented over a standard
        mutable <code>java.util.HashMap&lt;String, GroundedValue&gt;&gt;</code> on Java, or
        <code>System.Collections.Generic.Dictionary&lt;string, GroundedValue&gt;</code>
        on .NET. It is suitable only where the keys are all instances of <code>xs:string</code>
        (which means we don't need to retain the type annotation), and where no in-situ
        modification takes place. As soon as an operation such as <code>map:put</code>
        or <code>map:remove</code> is applied to the map, we make a copy using the
        more general <code>HashTrieMap</code> implementation. But for many maps,
        especially those derived from JSON parsing, incremental modification is rare,
        and the lower-overhead <code>DictionaryMap</code> is perfectly satisfactory.</p>
        
        <p>In Saxon 13 (not yet released), a third map implementation has been introduced:
        the <code>ShapedMap</code>. This is described in the article 
        <a href="https://blog.saxonica.com/mike/2024/08/maps-and-records.html">Maps and Records</a>,
        and it is particularly useful in cases where many maps have exactly the same structure.
        This often happens when parsing CSV or JSON files. A <code>ShapedMap</code> is in two
        parts: a <code>Shape</code> object which holds a mapping from keys to integer slot numbers,
        and a simple array of slots holding the values of the fields. The <code>Shape</code>
        object can be shared between all map instances having a common structure. As with the
        <code>DictionaryMap</code>, if a <code>ShapedMap</code> is subjected to <code>map:put</code>
        or <code>map:remove</code> operations, it is immediately copied to a <code>HashTrieMap</code>.</p>
        
        <p>How are these map implementations affected by the requirement to maintain order
        of entries?</p>
        
        <p>For the <code>ShapedMap</code>, order is already maintained, so it isn't a problem.
        The only impact is that two maps can only share the same <code>Shape</code> object
        if their keys are in the same order. There isn't going to be any observable performance
        regression.</p>
        
        <p>For the <code>DictionaryMap</code>, on the Java platform we can replace the
        underlying <code>HashMap&lt;String, GroundedValue&gt;</code> by a 
        <code>LinkedHashMap&lt;String, GroundedValue&gt;</code>. That's easily done,
        because it supports the same interface. I don't yet know how much overhead
        it imposes (in space or time); that requires some measurements.</p>
        
        <p>On .NET, unfortunately, there is no equivalent to Java's <code>LinkedHashMap</code>.
        I have therefore implemented my own: this comprises a <code>Dictionary&lt;string, int&gt;</code>
        that maps string-valued keys to integer positions in the sequence, and two lists:
        a list of <code>AtomicValue</code> for the keys and a list of <code>GroundedValue</code>
        for the values.</p>
        
        <p>For the <code>HashTrieMap</code> on Java, my plan is to scrap the immutable map implemented
        by Michael Froh, and substitute it with the <code>io.vavr.collection.LinkedHashMap</code>
        from the VAVR library, which appears to have the required semantics. Again, there appears
        to be no direct equivalent on .NET, so a home grown solution is again called for. My
        current implementation uses the same apprach as for the <code>DictionaryMap</code>:
        an immutable unordered map from atomic keys to integers, supplemented by ordered 
        immutable lists of <code>AtomicValue</code> for the keys and <code>GroundedValue</code>
        for the values.</p>
        
        <p>Which brings us to the question, what are the overheads? Answering that question
        means making some assumptions about the workloads we want to measure. For example,
        how important are <code>map:put</code> and <code>map:remove</code> operations? 
        Anecdotal evidence suggests these are rather rare, and that most maps are read-only
        once built. But they might be important to some use cases.</p>
        
        <p>The other complication is that we might be able to mitigate the overheads of making
        maps ordered by introducing new optimisations. We've already introduced the 
        <code>ShapedMap</code> idea, where ordering hopefully imposes very little overhead.
        On .NET we could consider taking advantage of the ability to use a custom 
        <code>KeyComparer</code> to avoid the overhead of effectively storing the keys twice.</p>
        
        <p>We could also get smarter about choosing which implementation of maps to use under
        which circumstances. One change that I'm making is to introduce a <code>MapBuilder</code>
        class: during the initial construction of a map (for example during JSON parsing or
        during processing of <code>map:merge</code> or <code>map:build</code>, or during
        evaluation of a map constructor) we can add entries to a mutable builder object, and
        this then gives us the opportunity to choose the final map implementation when we
        know what all the keys and values are. For example, if all the keys have the same
        type annotation, then in principle we don't need to save the type annotations with
        every key value. We also know the size of the map at this stage.</p>
        
        <p>We can even go further and avoid indexing the map until the first lookup 
        (or <code>map:get</code>) operation. It might seem surprising, but there
        are many maps that are never used for lookup. For example, a JSON document
        might contain thousands of maps that are simply copied unchanged to the output,
        or that are discarded because they are irrelevant to the particular query.
        Perhaps the map builder should simply maintain a list of keys and values,
        and do nothing else until the first <code>map:get</code>? The only complication
        here is the need to detect duplicate keys, but that could be done cheaply
        using a Bloom filter.</p>
        
        <p>So we need to do some measurements. But there's a good chance that if
        it does turn out that ordered maps impose an overhead, we can find compensating
        optimisations that mean there's no regression on the bottom line.</p>
        
        <p>My first experiments looking at the cost of parsing and re-serializing
        JSON actually suggest that most of the cost is in the parsing and serializing,
        and that the choice of data structure for the XDM maps has very little impact 
        on the bottom line. But that's provisional and subject to confirmation.</p>
        
        
        
  
 
   
    </div></content></entry><entry><title>Maps and Records</title><link href="https://blog.saxonica.com/mike/2024/08/maps-and-records.html" rel="alternate" type="text/html"/><id>https://blog.saxonica.com/mike/2024/08/maps-and-records.html</id><published>2024-08-10T09:00:00Z</published><content type="xhtml" xml:base="https://blog.saxonica.com/mike/2024/08/maps-and-records.html"><div xmlns="http://www.w3.org/1999/xhtml">
        
        
        <p>Maps have proved to be one of the most powerful new features in the 3.0/3.1 family of standards,
        and records, which extend the capability will probably prove one of the most powerful in 4.0. 
        Under the name <i>tuple types</i>, the feature has been available as a proprietary Saxon extension
        since Saxon 9.8, which came out on the same day as the XSLT 3.0 Recommendation in June 2017.
        The feature is now well established, but the details are still being refined.</p>
        
        <p>A record type is declared like this:</p>
        
        <pre>record(longitude as xs:double, latitude as xs:double)</pre>
        
        <p>A record type is simply a new way of constraining maps; the instances of the type
        are maps (in this case a map with two entries, one with key "longitude" and one with
        key "latitude"). You can use a record type to declare the types of variables and function
        arguments, but the actual value of the variable is a map, and all the standard map operations
        are available, such as the lookup operator: <code>$location?longitude</code>.</p>
        
        <p>We're working on an extension that allows named record types to be declared globally:</p>
        
        <pre>&lt;xsl:record name="my:location"&gt;
   &lt;xsl:field name="longitude" as="xs:double"/&gt;
   &lt;xsl:field name="latitude" as="xs:double"/&gt;
&lt;/xsl:record&gt;</pre>
        
        <p>which would also give you a constructor function: <code>my:location($long, $lat)</code>.</p>
        
        <p>The main thing I want to talk about in this article is how records can be efficiently
        implemented.</p>
        
        <p>Until recently, a record type simply constrained the contents of a map, and had no
        bearing on the way the map was implemented.</p>
        
        <p>Internally, Saxon represents maps using the interface <code>net.sf.saxon.ma.map.MapItem</code>
        (actually an abstract class), and there are several implementations of this interface:</p>
        
        <ul>
            <li><code>EmptyMap</code> for an empty map</li>
            <li><code>SingleEntryMap</code> for a map with one entry, such as the map created by <code>map:entry()</code></li>
            <li><code>DictionaryMap</code> for a map whose keys are all strings, and that isn't likely to be modified
            (for example maps derived by parsing JSON, or maps written using literal constructors as option parameter values)</li>
            <li><code>HashTrieMap</code> as the general implementation that handles everything.</li>
        </ul>
        
        <p>For the next release, Saxon 13, we've written a new implementation called a
        <i>ShapedMap</i>. There are two parts to this: a <i>Shape</i> is a mapping from field names to
        integer slot numbers, and a <i>ShapedMap</i> is a reference to a <i>Shape</i>, plus an array of slots.
        So it's great where you have many maps with exactly the same structure, because you only hold the keys
        once.</p>
        
        <p>So far we're mainly using shaped maps where the structure of the map is defined by the language specification,
        for example for the key-value pairs returned by <code>map:pairs()</code>, for the results of functions such as
        <code>parse-csv()</code>, <code>random-number-generator()</code>, and <code>load-xquery-module()</code>,
        and for the labels attached to values by the new deep-lookup operator (plenty of scope there for future articles).
        I would love to use them also for the result of <code>parse-json()</code> if we can detect the common case
        of a JSON file containing thousands of maps (JSON objects) with exactly the same structure. And of course, once
        we have record constructor functions as described above, they are an obvious candidate for the result
        of such a function.</p>
        
        <p>Shaped maps immediately give a space saving because the keys and their hash index are shared between instances.
        The next challenge after that is to make lookup on shaped maps more efficient. Given a lookup expression
        such as <code>$location?longitude</code>, we <i>ought</i> to be able to extract the corresponding value directly
        from slot 0 of the <code>ShapedMap</code> object, without the overhead of doing a run-time hash lookup of the string
        <code>"longitude"</code> in the corresponding <code>Shape</code> in order to establish that this field is always
        in slot 0.</p>
        
        <p>The obvious, classic way of doing that is through static type inference: if we know the static type of the
        <code>$location</code> variable, then we can know at compile time what the mapping of field names to slots will be,
        and can generate an execution plan accordingly.</p>
        
        <p>But I'm becoming a bit disillusioned with relying on static type analysis. Users, in general, are lazy: they
        want good performance without doing extra work, like declaring the types of all their variables. That's particularly
        true when you start writing code that relies heavily on higher-order functions, which we want to encourage.
        So I'm looking increasingly at options that decide the execution plan at run-time, modifying it in the light
        of actual experience. Given an expression like <code>$location?longitude</code> that is executed repeatedly,
        the chances are that if <code>$location</code> is a shaped map with <code>longitude</code> in slot 0 on one occasion,
        then the same will be true next time you execute the same expression.</p>
        
        <p>We've quietly introduced this kind of approach in recent releases, and it's working well. For example, with
        lazy evaluation of variables and function results we now use a learning approach: we start with lazy evaluation,
        but if on the first 20 executions the value is immediately read to completion, we switch to eager evaluation.
        That's because lazy evaluation has a significant set-up overhead to retain the parts of the context on which the
        expression depends, and there is no benefit in doing this if the caller is going to immediately materialise
        the value anyway.</p>
        
        <p>The concrete design for shaped record access goes something like this. We augment the 
            <code>MapItem</code> interface with a method
        <code>map.lookup(key, plan)</code>. This method returns the requested value from the map, but also updates the
        value of <code>plan</code> with information that will be retained the next time the same expression is evaluated.
        If the map is a shaped map, the returned plan can include the <code>Shape</code> and the slot number; if an incoming
        request comes with a plan that identifies the same <code>Shape</code> (which it usually will), 
        then we can access the relevant slot number directly,
        ignoring the value of the key. That only works, of course, for a lookup expression where the key is a literal
        constant; but that's the normal case when working with records.</p>
        
        <p>If we can make this work (and it seems straightforward), then the same approach might have other applications.
        For example, can we make path expressions go faster if we optimize for the tree model in use? Or could we get rid
        of statically-allocated fingerprints (with the inconvenience they cause by not allowing documents and stylesheets
        to be shared across configurations), and instead have the expression discover the fingerprint and NamePool at 
        execution time?</p>
        
        <p>Saxon is now 25 years old. It seems there are still plenty of exciting ways to make it better.</p>
        
        
        
 
 
   
    </div></content></entry><entry><title>All Change at Saxonica</title><link href="https://blog.saxonica.com/mike/2023/10/eot.html" rel="alternate" type="text/html"/><id>https://blog.saxonica.com/mike/2023/10/eot.html</id><published>2023-10-02T09:00:00Z</published><content type="xhtml" xml:base="https://blog.saxonica.com/mike/2023/10/eot.html"><div xmlns="http://www.w3.org/1999/xhtml">
        
        
        
        <p>Today we are announcing a big change at Saxonica, but it's one 
            that we hope no-one will notice.</p>
        
        <p>Some of you may have noticed that I will be 72 in a couple of weeks, 
        and you may have been wondering how long I intended to continue. 
        Well, I'm still enjoying the challenge, and I'm not giving up just yet, 
        but I have been thinking for some time about how to move the company 
        into a position where it can thrive without me. I decided a while ago 
        that the best approach — in the interests of the staff and the user community — 
        was to move the ownership of the company into an Employee Ownership Trust, 
        and this has now been effected.</p>
        
        <p>What this means is that Saxonica is now owned by a Trust, which 
        has acquired a 100% shareholding from my wife Penny and myself. 
        The Trustees are Norm Tovey-Walsh, Sue Schreiber, and myself, and their 
        task is to appoint directors and approve any big decisions (such as 
        acquisitions). When making such decisions the Trust is obliged to 
        take into consideration the best interests of the staff and the user 
        community, including both paying customers and open-source users.</p>
        
        <p>Indeed, there's a specific clause in the trust deed noting that the company's
        software is used to deliver open data for the wider benefit of society at large,
        and the Trustees are required to take this into account.</p>
        
        <p>The most obvious change will be that Norm Tovey-Walsh is taking over as Chief Executive; 
        I will remain on the board (with the title "Director of Innovation"), 
        but Norm is now the boss. I can't think of anyone in the world who 
        is better qualified to steer the ship.</p>
        
        <p>Back at the start of 2020, before the pandemic, I was rather conscious that
        with several people approaching retirement age,
        the company was not in a good state to carry on without me; as a result any 
        acquisition could well have led to serious discontinuity for the user community, 
        and indeed for the future of the XML ecosystem of which we have become such 
        a central part. Since then, with Norm joining in a senior technical role, 
        with Ankita Mohinta taking over the marketing and commercial side so effectively, 
        and more recently with Matt Patterson joining O'Neil Delpratt and Debbie Lockett 
        on the development side, we now have a team that has an unmatched depth of talent. 
        This is reflected in excellent financial results over the last couple of years. 
        But it's also true that I know the innards of the software better than anyone, 
        and I don't intend to walk away from my focus on providing technical support 
        to customers, which is probably the part of the job that I enjoy the most.</p>
        
        <p>Penny is taking this opportunity to retire from her role as a director 
        and employee of the company, and this is a good opportunity to thank 
        her for her contribution. She may not have been very visible externally, 
        but she's done a lot of invaluable admin work behind the scenes, 
        and has been a constant source of good advice, most particularly 
        in helping to build a happy and productive team — especially 
        through the pandemic.</p>
        
        <p>I'm confident that through this adminstrative change, the company will 
        retain the core values that have been central to our success: innovation, 
        commitment to standards, outstanding technical support, honesty and integrity, 
        admitting to our mistakes when we make them, and above all being active 
        contributors to the thriving community without which we would not exist. 
        I hope to remain part of that for many years to come.</p>
    </div></content></entry><entry><title>How Safe is your Schema?</title><link href="https://blog.saxonica.com/mike/2023/07/schema-safety.html" rel="alternate" type="text/html"/><id>https://blog.saxonica.com/mike/2023/07/schema-safety.html</id><published>2023-07-22T12:00:00Z</published><content type="xhtml" xml:base="https://blog.saxonica.com/mike/2023/07/schema-safety.html"><div xmlns="http://www.w3.org/1999/xhtml">
        
        
        <p>When you validate a document, you expect to set the rules for what it can contain.
        If you specify that your nesting box can only contain wrens and robins, you don't want
        any cuckoos in there.</p>
        
        <p>So you write a schema <code>nesting-box.xsd</code> like this:</p>
        
        <pre>&lt;xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    elementFormDefault="qualified"
    attributeFormDefault="unqualified"
    version="1.1"&gt;
    
    &lt;xs:element name="nesting-box" type="nesting-box-type"/&gt;
    
    &lt;xs:complexType name="nesting-box-type"&gt;
        &lt;xs:choice minOccurs="0" maxOccurs="unbounded"&gt;
            &lt;xs:element ref="wren"/&gt;
            &lt;xs:element ref="robin"/&gt;
        &lt;/xs:choice&gt;
    &lt;/xs:complexType&gt;
    
    &lt;xs:element name="wren" type="xs:string"/&gt;
    &lt;xs:element name="robin" type="xs:string"/&gt;
&lt;/xs:schema&gt;         
        </pre>
        
        <p>And you're now comfortable that any <code>&lt;nesting-box&gt;</code> that
            passes validation will look something like this:</p>
        
        <pre>&lt;nesting-box&gt;
   &lt;wren&gt;Nice!&lt;/wren&gt;
   &lt;robin&gt;Nicer!&lt;/robin&gt;
   &lt;robin&gt;Nicest!&lt;/robin&gt;
&lt;/nesting-box&gt;
        </pre>
        
        <p><b><i>You're wrong!</i></b></p>
        
        <p>The following document also passes validation:</p>
        
        <pre>&lt;nesting-box xsi:schemaLocation="cuckoo.ns cuckoo.xsd" 
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
   &lt;wren&gt;Nice!&lt;/wren&gt;
   &lt;robin&gt;Nicer!&lt;/robin&gt;
   &lt;robin&gt;Nicest!&lt;/robin&gt;
   &lt;cuckoo xmlns="cuckoo.ns"&gt;Horrid!&lt;/cuckoo&gt;
&lt;/nesting-box&gt;
        </pre>
        
        <p>Here <code>cuckoo.xsd</code> is another schema document, like this:</p>
        
        <pre>&lt;xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    elementFormDefault="qualified"
    attributeFormDefault="unqualified"
    targetNamespace="cuckoo.ns"
    version="1.1"&gt;
    
    &lt;xs:import schemaLocation="nesting-box.xsd"/&gt;
    
    &lt;xs:element name="cuckoo" type="xs:string"
       substitutionGroup="robin"/&gt;
    
&lt;/xs:schema&gt;
        </pre>
        
        <p>So you thought you were constraining what could appear in the document,
        and the user found a way past your defenses, submitting a document that
        your code probably can't handle.</p>
        
        <p>Saxon does allow you to disable use of <code>xsi:schemaLocation</code>,
        but it's enabled by default. I'm inclined to think the default needs to
        be changed.</p>
        
 
   
    </div></content></entry><entry><title>Schema Modularity</title><link href="https://blog.saxonica.com/mike/2023/06/schema-modules.html" rel="alternate" type="text/html"/><id>https://blog.saxonica.com/mike/2023/06/schema-modules.html</id><published>2023-06-20T12:00:00Z</published><content type="xhtml" xml:base="https://blog.saxonica.com/mike/2023/06/schema-modules.html"><div xmlns="http://www.w3.org/1999/xhtml">

            

        <p>Saxon, ever since we first introduced schema awareness back in 2004, has always
        worked with a single global schema maintained at the level of the <code>Configuration</code>
        object. This article discusses the advantages and disadvantages of this approach, and
        looks at possible alternatives.</p>
        
        <p>Let's start by getting some terminology clear. A <b>schema</b>, in the terminology
        of the XSD specification, is a set of schema components (such as element declarations
        and type definitions). Don't confuse it with a <b>schema document</b>, which is an
        XML document rooted at an <code>xs:schema</code> element. A <b>schema</b>
        is what you get when you compile a collection of schema documents linked to each
        other using <code>xs:include</code> and <code>xs:import</code> declarations.</p>
        
        <p>Not every set of schema components constitutes a valid schema. Most obviously
        you can't have two different components (for example, two type definitions) with the
        same name, unless they are identical. The XSD specification is a bit fuzzy about what
        it means for two components to be identical.</p>
        
        <p>This means that in general, you can try and combine two schemas into one by
        taking their union, but the operation won't always succeed because the two
        schemas may be found to be inconsistent with each other.</p>
        
        <h2>The Global Schema</h2>
        
        <p>Saxon currently maintains a global schema at the level of the <code>Configuration</code>
        object. This means that every time you introduce a new schema, for example by
        compiling a schema-aware query or stylesheet that has an <code>import schema</code> declaration,
        or by validating a document against a schema loaded using the <code>SchemaManager</code>
        API, or referenced using <code>xsi:schemaLocation</code>, the schema components
        from that schema are added to the global pool, provided they are consistent with
        the declarations already present in the pool.</p>
        
        <p>These consistency checks are of two kinds:</p>
        
        <ul>
            <li><p>Firstly, the new components must not have names that clash with the old.
            You can't have two different types with the same name. To test whether two types
            are the same, Saxon basically checks that they came from the same place: the same
            line number in the same source schema document.</p></li>
            <li><p>Secondly, the new components must not change the semantics of existing
            components, if the existing components have already been used for validation purposes.
            The test whether components have been used is done at the level of a target
            namespace: if any declaration or definition in a target namespace has been
            used for validating a source document, or if it has been used when compiling
            a stylesheet or query, then the namespace is <b>sealed</b>, which means that its
            components must not be extended or redefined by any new components.
            We'll talk later about exactly what this means.</p></li>
        </ul>
        
        <p>The main benefit of the global schema approach is that you can always be sure
        that type annotations in validated instance documents are consistent with types
        that are mentioned (or inferred) in compiled queries and stylesheets. If a query
        is compiled believing that element <i>E</i> will always be empty, then you can be sure
        that every validated instance of <i>E</i> will be empty, because no-one is allowed, between
        compilation and validation, to add a type definition that extends or redefines <i>E</i>
        allowing it to be non-empty. That's the theory, anyway.    
        </p>
        
        <p>The most obvious <i>disadvantage</i> of the approach is that an application can't
        work with two different versions of the same schema. If you want to write a stylesheet
        that transforms input documents from <i>V1</i> to <i>V2</i> of the same schema, you
        can't import both versions into the same stylesheet, one to validate the input and one
        to validate the output. In fact, you can't even have both versions in the same
        <code>Configuration</code> — which means you can't process an input collection containing
        a mix of different versions (or if you do, you have to forgo validation).</p>
        
        <p>There are other less obvious disadvantages. One of them is revealed by a recent
        embarrassing bug where we discovered that schema compilation isn't thread safe: you
        can't reliably run two schema compilations within a single <code>Configuration</code>
        at the same time. We've patched that by adding some locking, but it's an imperfect
        solution because the lock is rather coarse-grained. We need to find a better solution,
        and that gives us an opportunity to re-examine the design and see whether we can fix some
        other long-standing issues at the same time.</p>
        
        <p>Another outstanding issue is a long-standing bug #3531, concerning a situation where
        two independently-loaded schemas <i>X</i> and <i>Y</i> both extend the same substitution
        group. This has remained outstanding because we have had no reports of users being affected
        by it; but it remains an unsatisfactory state of affairs.</p>
        
        <h2>The X+Y Problem</h2>
        
        <p>Suppose that <i>X</i> and <i>Y</i> are valid schemas. Then we've already seen
        that their union, which I will call <i>X+Y</i>, is not necessarily a valid schema;
        their declarations might be inconsistent. Apart from the obvious inconsistencies
        where <i>X</i> and <i>Y</i> contain different elements or types with the same name,
        there can be much more subtle inconsistencies:</p>
        
        <ul>
            <li><p><i>Y</i> might contain a type that redefines a type in <i>X</i>.</p>
            <p>The semantics of <code>xs:redefine</code> as defined in XSD are a bit
            fuzzy round the edges, but the effect is supposed to be global: if a type
            is redefined, then all references to that type are affected. Exactly what
            happens when the same type is redefined more than once isn't made clear.
            </p>
            <p>The introduction of <code>xs:override</code> in XSD 1.1 makes this
            problem even worse, because <code>xs:override</code> allows existing
            definitions to be changed in completely arbitrary ways.</p></li>
            <li><p><i>Y</i> might contain a type that extends a type in <i>X</i>,
            by allowing additional child elements or attributes. To be valid, 
            instances that use the extended type have to identify themselves
            with an <code>xsi:type</code> attribute, but this doesn't alter the
            fact that adding the extended type to the global schema makes some
            things valid that were previously invalid. It's bad news if a document
            that was invalid at breakfast time suddenly becomes valid at tea time
            because a new schema has been added to the <code>Configuration</code>.
            It's even worse news if the schema changes during the course of
            validating an input document. </p></li>
            <li><p><i>Y</i> might contain an element declaration that
            adds to the substitution group of an element defined in <i>X</i>.
            Again, this means that a document that was invalid when validated
            against schema <i>X</i> becomes valid when validated against
            <i>X+Y</i>.</p></li>
            <li><p><i>X</i> might contain a wildcard, for example 
                <code>&lt;xs:any processContents="lax"/&gt;</code>. Suppose
            an instance document matches this wildcard with an element
            named <i>W</i>, and is valid (under the rules for lax validation)
            because the schema contains no element declaration for <i>W</i>.
            Now schema <i>Y</i> comes along and adds a definition for
            element <i>W</i>, and suddenly our source document is no
            longer valid.</p></li>
        </ul>
        
        <p>It doesn't really help that all these situations are rare. Should the
        processor simply ignore the problem and hope it doesn't happen? For the first
        three cases above, Saxon prevents the situation occurring, which imposes an
        inconvenience on users who are actually doing something completely safe.
        For the final case (wildcards), Saxon ignores the problem, which creates
        the theoretical risk that queries and stylesheets are not type-safe: a document
        that has been validated against a type <i>T</i> might not satisfy all the contraints
        that the query or stylesheet processor assumes to be true for any valid instance
        of <i>T</i>.</p>
        
        <h2>An Alternative: Modular Schemas</h2>
        
        <p>Let's consider an alternative model, where instead of adding all schema
        components to a single global schema at <code>Configuration</code> level,
        we keep schemas independent and modular. So two stylesheets that import
        different schema documents have separate unrelated schemas, and there are
        no requirements that the two schemas should be consistent with each other.</p>
        
        <p>The challenge now is to ensure that a source document validated against
        a schema <i>S1</i> is consistent with a stylesheet that imports schema <i>S2</i>.
        If the two schemas are identical, there's no problem (and it's not too hard to
        detect that they are identical, for example if they load the same schema
        document as their starting point).</p>
        
        <p>But what if <i>S2</i> is a superset of <i>S1</i>? Suppose the document is
        validated against a schema with target namespace <i>X</i>, while the stylesheet
        has two <code>xsl:import-schema</code> declarations, for namespaces <i>X</i> 
        and <i>Y</i>? We're now back with the <i>X+Y</i> problem: a document that is valid
        against <i>X</i> is not necessarily valid against <i>X+Y</i>.</p>
        
        <p>It gets worse: if we have a pipeline of stylesheets, each of which imports
        schemas for both its input document and its output document, then the first
        stylesheet might import schemas for <i>X+Y</i>, and the second for <i>Y+Z</i>,
        and we need to be sure that when the first stylesheet validates its output against
        <i>X+Y</i>, the result will also be valid input against <i>Y+Z</i>.</p>
        
        <p>One possible solution here is to keep the imported schemas within a single
        stylesheet separate. Import one schema for the input, and another for the output,
        and don't require the two to be consistent. This also solves the problem of transforming
        from <i>V1</i> to <i>V2</i> of the same schema. So in our pipeline, the output
        of the first stylesheet would be validated not against <i>X+Y</i>, but merely
        against <i>Y</i>, which is the same schema used for the input of the second stylesheet.
        This would need language changes: <code>xsl:import-schema</code> declarations
        would need to identify which schema they belong to, and type names used in 
        <code>type</code> or <code>as</code> attributes would need to qualify the type
        name with a schema name.</p>
        
        <p>I've started doing work to allow free-standing schemas to be constructed
        and used for validation, independently of the <code>Configuration</code>.
        There are clearly cases where this is useful. However, there's a lot more
        work to be done on ensuring consistency of free-standing schemas, when a validated
        document is used as input to a schema-aware stylesheet or query. Expect a new
        class of (initially bewildering) error messages saying that element <i>E</i>
        is known to be valid against type <i>T</i> in schema <i>X</i>. but it isn't known
        to be valid against type <i>T</i> in schema <i>Y</i>. Hopefully these will be rare.</p>
        
        <h2>What about Wildcards?</h2>
        
        <p>I mentioned that there's an open issue with wildcards: if a schema type include
        a lax wildcard, then an element that's valid against that schema (because there's
        no element declaration matching the actual element name) can become invalid when
        more element declarations are added.</p>
        
        <p>This isn't the only issue with wildcards. XSD 1.1 allows you to say, for example
        <code>notQName="##defined"</code> which means that the name used for an element or
        attribute must be one that has no global declaration anywhere in the schema. That's
        another example of how adding new declarations to a schema can make existing content
        invalid.</p>
        
        <p>I think the answer to this problem is to interpret these definitions in the context
        of a "schema compilation unit". That is, when you compile a schema, 
            <code>notQName="##defined"</code> is interpreted as meaning "not a name used for
        a global element/attribute declaration in the that schema"; any
        names or declarations added later (by merging this schema with others) have no effect 
        on the meaning.</p>
        
        <p>This seems to solve the problem whether using a global schema or local free-standing
        schemas, and makes the two cases behave more consistently and predictably.</p>
        
    </div></content></entry><entry><title>The pattern match="para except appendix//para"
      </title><link href="https://blog.saxonica.com/mike/2022/05/except-patterns.html" rel="alternate" type="text/html"/><id>https://blog.saxonica.com/mike/2022/05/except-patterns.html</id><published>2022-05-26T15:15:00Z</published><content type="xhtml" xml:base="https://blog.saxonica.com/mike/2022/05/except-patterns.html"><div xmlns="http://www.w3.org/1999/xhtml">
        <h1>The pattern <code>match="para except appendix//para"</code></h1>
        
        <p>If you saw this pattern in an XSLT stylesheet, I can guess your reaction: <i>I haven't
        seen a pattern like that before. Cool, a neat way of matching paragraphs that aren't in
        an appendix. Must remember that and use it myself.</i></p>
        
        <p>Sadly, it doesn't do what you think. Consider this input document:</p>
        
        <pre><code>
&lt;appendix id="A"&gt;
    &lt;section id="A.1"&gt;
        &lt;para&gt;Ipsum lorem.&lt;/para&gt;
    &lt;/section&gt;
&lt;/appendix&gt;                   
        </code></pre>
        
        <p>You'd probably be as surprised as I was to see that the <i>Ipsum lorem</i> paragraph in this
            example matches the pattern <code>para except appendix//para</code>.</p>
        
        <p>To see why this is true, go to the spec, section 5.5.3: </p>
        
        <p>An item <i>N</i> matches a pattern <i>P</i> if the following applies, where <i>EE</i> is the equivalent expression to <i>P</i>: 
            <i>N</i> is a node, and the result of evaluating the expression <code>root(.)//(EE)</code> with a singleton 
            focus based on <i>N</i> is a sequence that includes the node <i>N</i>.</p>
        
        <p>So, this is saying that a node matches the pattern if it is selected by the expression <code>root(.)//(para except appendix/para)</code>.
        Assuming that we're in a tree rooted at a document node, that means it must be selected by the expression 
        <code>/descendant-or-self::node()/(para except appendix//para)</code>.</p>
        
        <p>Now, in our example document, one of the nodes selected by <code>/descendant-or-self::node()</code> is the <code>section</code> element;
            and when we evaluate <code>(para except appendix//para)</code> starting at the <code>section</code> element, the first operand
            (<code>para</code>) selects our paragraph, and the second operand (<code>appendix//para</code>) doesn't select it, so
        the expression as a whole selects it, and therefore it matches the pattern.</p>
        
        <p>That's totally counter-intuitive, and it's certainly not what the Working Group intended. It's a nasty bug. So the question is,
        what can we do about it, given that this is a published spec and there are implementations out there, and user applications that
        depend on it?</p>
        
        <h2>Is there anything we can do about it?</h2>
        
        <p>Perhaps we should start by asking: what would we like the spec to say, if we had the opportunity to change it?</p>
        
        <p>Given that we already have a special rule for patterns with a top-level <code>union</code> operator (see §6.5 rule 2),
        we could add a special rule for patterns with a top-level <code>intersect</code> or <code>except</code>
            operator: a pattern of the form <code>A except B</code> matches an item if pattern <i>A</i> matches the item and 
            pattern <i>B</i> does not. (And analagously for <code>intersect</code>.)</p>
        
        <p>If that's what we think we need to do, that leaves two challenges:</p>
        
        <ul>
            <li>Changing the spec (given there is no longer a Working Group to maintain it).</li>
            <li>Changing the Saxon implementation.</li>
        </ul>
        
        <p>Starting with the second point, there are several possibilities:</p>
        
        <ul>
            <li>Just do it, and hope we don't break any existing applications.</li>
            <li>Support both the old and new semantics concurrently, with some mechanism for selecting which to use. (Which should
            be the default? We want new users not to fall into the elephant trap, but we also don't want to break working applications.)</li>
            <li>Deprecate the syntax, and provide new syntax for the new semantics (e.g. operators spelled <code>and-also</code> or
            <code>but-not</code>). Note however, that it's likely most applications currently using <code>except</code> in a pattern
            are using unproblematic patterns like <code>@* except @code</code>.</li>
        </ul>
        
        <p>The third option seems the most satisfactory. And that suggest a route forward for the spec: in XSLT 4.0, if and when we
        manage to get it defined, deprecate the <code>except</code> and <code>intersect</code> operators at the top level of a pattern,
        and replace them with new operators that have the expected intuitive semantics.</p>
        
    
    </div></content></entry><entry><title>XML versus JSON: A Comparison using the XMark Benchmark</title><link href="https://blog.saxonica.com/mike/2022/05/xml-vs-json.html" rel="alternate" type="text/html"/><id>https://blog.saxonica.com/mike/2022/05/xml-vs-json.html</id><published>2022-05-06T11:00:00Z</published><content type="xhtml" xml:base="https://blog.saxonica.com/mike/2022/05/xml-vs-json.html"><div xmlns="http://www.w3.org/1999/xhtml">
        
        
        <p>For many years we have used the XMark benchmark to check for performance
        regression between Saxon releases, and to evaluate the impact of internal
        changes on query performance.</p>
        
        <p>XMark originated with the MonetDB project and is described at
            <a href="https://projects.cwi.nl/xmark/">https://projects.cwi.nl/xmark/</a>. It consists
        of a scaleable XML data file (produced using a data generator), and a set of 20 XQuery queries
        to be run against that data file. We have run the data generator to produce files with
        nominal sizes of 100Kb, 1Mb, 4Mb, 10Mb, and 100Mb; we use the original queries as published,
        except for one or two small changes to correct errors in the original publication.</p>
        
        <p>Recently we have converted these data files to JSON, and have produced equivalent XQuery 3.1
        queries to deliver the same results as the original. The queries still produce XML rather than JSON
        output, so that we can compare the results; except in a few cases where large chunks of the original
        XML are copied to the output, which we cannot reproduce exactly because we don't have the original
        XML available. The results also differ because JSON maps don't retain order.</p>
        
        <p>In this article I will report first on the data conversion; then on the query conversion;
        and finally on performance results.</p>
        
        <h2>Converting the data</h2>
        
        <p>I didn't attempt to use any off-the-shelf XML-to-JSON conversion tools. My instinct is that they
        wouldn't have done a very good job, and I would have needed an XSLT transformation to refine the output
        anyway, so I decided to do the whole job using XSLT 3.0.</p>
        
        <p>The conversion stylesheet is not particularly interesting; in fact, it's rather tedious. A few points
        are worth mentioning:</p>
        
        <ul>
            <li><p>As mentioned in <a href="/mike/2021/06/arrays.html">What should
            we do about arrays?</a> the XSLT 3.0 spec is weak on capabilities for constructing arrays. This
            is the only area where we used Saxon extensions. I'm not convinced we yet have a perfect solution to this
            problem, and I've proposed some new ideas at <a href="https://github.com/qt4cg/qtspecs/issues/113">Constructing Arrays</a>.</p></li>
            <li><p>The XMark data files are mainly structured data, but there is some use of mixed content for narrative
            text. Mixed content is bad news for JSON. In real life, I would probably have handled this by embedding
            XML or HTML fragments within character strings in the JSON structure; but that seemed to be against
            the spirit of this exercise, so I instead expanded the node structure of the mixed content using JSON
            maps and arrays. As we'll see later, this had a severe effect on the ease of writing the queries
            and on their performance.</p></li>
            <li><p>Most structured data elements in the original file fall into two categories: elements
            with homogenous element content (multiple children all having the same name), and elements
            with heterogeous element content (multiple children with different names). These translate very
            naturally into JSON arrays and maps respectively. A few cases weren't quite so simple: for example
            the content model for <code>open_auction</code> has the form <code>(initial, bidder*, current,
            privacy, seller, ...)</code>. We handle this as if there were a wrapper element <code>bidders</code>
            around the sequence of <code>bidder</code> elements, so <code>open_auction</code> translates
            to a map, and <code>bidders</code> converts to an array. The names of elements within an array
            are generally dropped.</p></li>
            <li><p>There are a few attributes in the XML; these posed no particular problem.</p></li>
        </ul>
        
        <p>The nominal 10Mb file is actually 11,875,066 bytes in its XML form, and 10,464,266 bytes
        when converted to JSON, a reduction of 13%. Some of this difference (perhaps 200Kb) is due to 
        unnecessary whitespace in the XML; the rest is the overhead of element end tags.</p>
        
        <p>Parsing the XML and building a Saxon TinyTree took 353ms; parsing the JSON and building a structure
        of XDM maps and arrays took 636ms. I haven't attempted to assess the memory usage of the two data structures,
        but the maps and arrays are almost certainly larger. This is despite the fact that for maps derived directly
        from JSON parsing, we use a specialized representation of maps that optimizes for the fact that all keys
        are instances of <code>xs:string</code>, and therefore don't need to retain a type annotation.</p>
        
        <h2>Converting the Queries</h2>
        
        <p>The queries were converted by hand. Generally we tried to change the query so it continued to produce
        the same (XML) output as the original, for ease of comparing results; but for queries whose output copies
        sizeable chunks of the input XML, we abandoned this principle, instead replicating the intent of the query
        as far as we could.</p>
        
        <p>In most cases the conversion is very straightforward. For example, this is Q3:</p>
        
        <pre><code>
(: Q3. Return the IDs of all open auctions whose current
     increase is at least twice as high as the initial increase. :)

for    $b in /site/open_auctions/open_auction
where  $b/bidder[1]/increase * 2 &lt;= $b/bidder[last()]/increase
return &lt;increase first="{$b/bidder[1]/increase}"
                 last="{$b/bidder[last()]/increase}"/&gt;            
            
        </code>           
        </pre>
        
        <p>Which turns into:</p>
        <pre><code>
(: Q3. Return the IDs of all open auctions whose current
     increase is at least twice as high as the initial increase. :)

for    $b in ?open_auctions?*
where  $b?bidders?*[1]?increase *2 &lt;= $b?bidders?*[last()]?increase
return &lt;increase first="{$b?bidders?*[1]?increase}"
                 last="{$b?bidders?*[last()]?increase}"/&gt;
        </code>           
        </pre>
        
        <p>Some observations:</p>
        
        <ul>
            <li>We have to use <code>bidders?*[1]</code> rather than <code>bidders?1</code> because
            the latter expression throws a dynamic error (rather than returning an empty sequence)
            for an auction in which there are no bidders.</li>
            <li>We use <code>bidders?*[last()]</code> to get the last item in an array
            because converting the array to a sequence and using a filter is simpler than the alternative of
            writing <code>bidders?(array:size($b?bidders))</code>.</li>
            <li>The element name <code>site</code> is dropped because the JSON file is a map in which
            <code>open_auctions</code> is a top-level entry.</li>
            <li>The element name <code>open_auction</code> is dropped because the 
                <code>open_auctions</code> entry in the JSON contains an array of objects which do
                not need to be named; the <code>?*</code> in the JSON query corresponds to the
                <code>/open_auction</code> in the original.</li>
            <li>The JSON form introduces the name <code>bidders</code> as a wrapper for the group of
            individual <code>bidder</code> elements in the XML (which become anonymous in the JSON).</li>
        </ul>
        
        <p>Some specific difficulties that were encountered in converting other queries:</p>
        
        <ul>
            <li>Query Q4 looks for auctions where one bid differs from a previous bid, and for this
            purpose it uses the operator <code>&lt;&lt;</code> to test the relative order of two
            nodes in document order. The JSON model offers no equivalent. To solve this I introduced
            a higher-order function <code>index-where(array, predicate)</code> which returns the
            index positions in an array of members that satisfy the given predicate; it is then possible
            to find the required two items and compare their index positions.</li>
            <li>For any query using the mixed content <code>description</code> field, I needed to include
            a recursive function that reconstructs the <code>description</code> as text by flattening
            the arrays and maps that make it up. This is tedious and expensive. Queries that do a deep dive
            into the description, like looking for text marked up with <code>keyword</code> tags at any
            depth, are even more complicated. The <code>map:find</code> function sometimes does what's needed,
            but not if any context is involved (for example, finding a keyword that's nested within 
            <code>emph</code> markup).</li>
            <li>Debugging mistakes can be tricky. The diagnostics you get when you write 
                <code>?closed_auctions?annotation</code> instead of <code>?closed_auctions?*?annotation</code>
            aren't always helpful. I've tried to improve them. I've also proposed a language change so
            the first expression becomes valid: see <a href="https://github.com/qt4cg/qtspecs/issues/115">Lookup
            operator on arrays of maps</a>.</li>
            <li>It's very easy to forget that if <code>$A</code> is an array, then <code>$A[$index]</code>
            and <code>$A[condition]</code> are both valid, but neither means what you think, because they treat
            the array as a single item, not as a collection. With arrays derived from JSON, every member of the
            array (discounting any nulls) is a singleton, so you can always write <code>$A?*[$index]</code>
                or <code>$A?*[condition]</code> instead.</li>
        </ul>
        
        
        
        
        <h2>Query Performance</h2>
        
        <p>For most of the queries, the JSON query was a little slower than the XML version. 
            Queries in this category include: </p>
        
        <table>
            <thead>
                <tr>
                    <th>Query</th>
                    <th>XML timing (ms)</th>
                    <th>JSON timing (ms)</th>
                    <th>Ratio (%)</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>q1</td>
                    <td>0.2649</td>
                    <td>0.6845</td>
                    <td>258%</td> 
                </tr>
                <tr>
                    <td>q2</td>
                    <td>0.4861</td>
                    <td>0.6588</td>
                    <td>136%</td> 
                </tr>
                <tr>
                    <td>q5</td>
                    <td>0.2711</td>
                    <td>0.3190</td>
                    <td>118%</td> 
                </tr>
                <tr>
                    <td>q8</td>
                    <td>1.9359</td>
                    <td>2.3572</td>
                    <td>122%</td> 
                </tr>
                <tr>
                    <td>q10</td>
                    <td>11.3329</td>
                    <td>14.3428</td>
                    <td>127%</td> 
                </tr>
                <tr>
                    <td>q11</td>
                    <td>93.5360</td>
                    <td>144.1105</td>
                    <td>154%</td> 
                </tr>
                <tr>
                    <td>q16</td>
                    <td>0.4183</td>
                    <td>0.8489</td>
                    <td>203%</td> 
                </tr>
                <tr>
                    <td>q17</td>
                    <td>0.5964</td>
                    <td>0.8887</td>
                    <td>149%</td> 
                </tr>
                <tr>
                    <td>q20</td>
                    <td>1.2380</td>
                    <td>2.2084</td>
                    <td>178%</td> 
                </tr>
            </tbody>
        </table>
        
        <p>How do we account for these numbers? My theory (based on gut feeling) is that the XML queries
        are faster because of the use of integer fingerprints for name matching in the TinyTree. Look at
        q1, for example, which in the original is:</p>
        
        <p>Q1: <code>for $b in /site/people/person[@id="person0"] return $b/name</code></p>
        
        <p>(The XMark queries were written by someone who felt that everything ought to be written
        as a FLWOR expression. It can of course be simplified to a simple XPath. I'm surprised
        they didn't use a <code>where</code> clause...)</p>
        
        <p>The child and attribute axis steps here (<code>child::people</code>, <code>child::person</code>, 
            <code>attribute::id</code>etc) are implemented
        in the TinyTree by a sequential search of node entries testing each one for an integer namecode. By contrast
        the JSON equivalent is:</p>
        
        <p>Q1: <code>for $b in ?people?*[?id="person0"] return $b?name</code></p>
        
        <p>and this involves string-based lookups in a hash table. Because the fan-out is fairly small, the
        sequential search wins.</p>
        
        <p><i>To test this theory, I ran the XML queries using DOM rather than TinyTree as the tree model. Navigation
            in the DOM uses string matching on element and attribute names. The DOM queries
        are dramatically slower than the TinyTree: q1: 0.2947 q2: 9.1684 q5: 5.1841 q8: 49.4798 q10: 116.8379 
        q11: 402.2151 q16: 6.5635 q17: 44.1887 q20: 179.2854.</i></p>
        
        <p>In the next group of queries, the JSON query is slightly faster:</p>
        
        <table>
            <thead>
                <tr>
                    <th>Query</th>
                    <th>XML timing (ms)</th>
                    <th>JSON timing (ms)</th>
                    <th>Ratio (%)</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>q3</td>
                    <td>1.3507</td>
                    <td>1.2656</td>
                    <td>94%</td> 
                </tr>
                <tr>
                    <td>q6</td>
                    <td>0.2870</td>
                    <td>0.0316</td>
                    <td>11%</td> 
                </tr>
                <tr>
                    <td>q9</td>
                    <td>3.2959</td>
                    <td>2.2320</td>
                    <td>68%</td> 
                </tr>
                <tr>
                    <td>q12</td>
                    <td>32.3911</td>
                    <td>29.2320</td>
                    <td>90%</td> 
                </tr>
                <tr>
                    <td>q18</td>
                    <td>0.3134</td>
                    <td>0.2865</td>
                    <td>91%</td> 
                </tr>
                <tr>
                    <td>q19</td>
                    <td>4.9937</td>
                    <td>4.6699</td>
                    <td>93%</td> 
                </tr>
            </tbody>
        </table>
        
        <p>Query q6 is clearly an outlier. This query counts descendants: the original XML formulation is:</p>
        
        <p>Q6: <code>for $b in /site/regions/* return count ($b//item)</code></p>
        
        <p>As it happens, <code>item</code> elements cannot appear at any depth, so the return clause
        could equally have been written <code>count($b/item)</code>. In writing the JSON query I took
        advantage of this knowledge, and wrote the query as:</p>
        
        <p>Q6: <code>map:for-each(?regions, function($k, $v){a:size($v)})</code></p>
        
        <p>This runs faster firstly because of this simplification, and secondly because the size of a map
        can be determined in constant time, whereas counting the number of children of an element requires
        actually scanning them.</p>
        
        <p>For the other queries where there is a small speed-up, the cause is less obvious, but it's usually
        possible to hazard a guess. Some of them, for example, involve arithmetic and numeric comparisons,
        and the JSON queries in such cases avoid the overhead of converting strings to numbers on the fly
        (instead, the conversion is done during JSON parsing). We know from profiling that these conversions,
        especially if they occur in a filter predicate, can dominate query execution time.</p>
        
        <p>For the final group of queries, the JSON performance is chronically worse:</p>
        
        <table>
            <thead>
                <tr>
                    <th>Query</th>
                    <th>XML timing (ms)</th>
                    <th>JSON timing (ms)</th>
                    <th>Ratio (%)</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>q7</td>
                    <td>1.0953</td>
                    <td>87.4869</td>
                    <td>7987%</td> 
                </tr>
                <tr>
                    <td>q13</td>
                    <td>0.3635</td>
                    <td>15.1646</td>
                    <td>4171%</td>
                </tr>
                <tr>
                    <td>q14</td>
                    <td>12.4252</td>
                    <td>138.0764</td>
                    <td>1111%</td>
                </tr>
            </tbody>
        </table>
        
        <p>These three queries all involve access to the <code>description</code> of an <code>item</code>, which in the XML representation
        is a mixed-content field (text with inline markup). As remarked earlier, this has been represented in JSON by expanding the
        node tree to a structure of arrays and singleton maps. As a result, a query like this one:</p>
        
        <p>Q14: <code>for $i in /site//item where contains ($i/description,"gold") return ($i/name, $i/description)</code></p>
        
        <p>becomes thoroughly contorted (and inefficient) in the JSON representation: it is necessary to write a recursive function
        that assembles the description (sans markup) as a string before executing the <code>contains()</code> function. Even then,
        the JSON query doesn't faithfully reproduce the original, because it outputs the description as a string, losing the internal
        markup.</p>
        
        <h2>Conclusions</h2>
        
        <p>First, if you've got mixed content (text with inline markup) then you probably don't want to be using JSON. If you must
        use JSON, use XML or HTML within character strings in cases where inline markup is needed.</p>
        
        <p>Secondly, for structured data it's a fairly even match; the differences aren't large enough to be critical for most
        applications. In Saxon, XML does slightly better on balance. This assumes, however, that for the XML case you are using 
        an efficient model like the Saxon TinyTree, rather than a general-purpose DOM.</p>
        
        <p>We found a few cases where the expressive power of XQuery 3.1 for querying JSON structures has gaps and omissions.
        Notably, searching for descendants in the tree is difficult; operations based on ordering of items within arrays are
        also tricky.</p>
            
    </div></content></entry><entry><title>What should we do about Arrays?</title><link href="https://blog.saxonica.com/mike/2021/06/arrays.html" rel="alternate" type="text/html"/><id>https://blog.saxonica.com/mike/2021/06/arrays.html</id><published>2021-06-27T15:34:00Z</published><content type="xhtml" xml:base="https://blog.saxonica.com/mike/2021/06/arrays.html"><div xmlns="http://www.w3.org/1999/xhtml">
        
            
            <p>Arrays were added to the data model for XPath 3.1 (and XQuery 3.1): the main motivation 
                was the need for faithful representation of JSON data structures, while a secondary 
                consideration was the long-standing requirement for "sequences of sequences".
            </p>
            <p>Processing support for arrays in the current languages is rather limited. There's 
                a basic set of functions available, but not much else. Support in XSLT 3.0 is 
                particularly weak, because XSLT 3.0 was primarily designed to work with XPath 3.0 
                (which didn't have arrays), with 3.1 support added as something of an afterthought.
            </p>
            <p>This note surveys where the gaps are, and how they should be filled.
            </p>
            <p>Many of the complications in processing arrays arise because the members of an array 
                can be arbitrary sequences, not just single items. There were two reasons for this 
                design. One is simply orthogonality: the principle of no unnecessary restrictions. 
                The other was support for the JSON null value, which maps naturally to an empty 
                sequence in XDM, but only if an array is allowed have an empty sequence as one of its members.
            </p>
            
            <h2>Array Construction</h2>
            
            <p>XPath 3.1 offers two constructs for creating arrays: the "square" and "curly" 
                constructors. Neither is completely general. The "square" constructor (for 
                example <code>[$X, $Y, $Z]</code>) can construct an array with arbitrary values as its 
                members, but the size of the array needs to be known statically. The "curly" 
                constructor (for example <code>array{$X, $Y, $Z}</code>) can construct an array whose size 
                is decided dynamically, but the members of the array must be singleton items 
                (not arbitrary sequences). The WG failed to come up with a construct for creating 
                an array where both the size of the array and the size of each member are 
                determined dynamically. The only way to achieve this is with a fairly convoluted 
                use of functions such as <code>array:join()</code>.
            </p>
            <p>XSLT 3.0 has no mechanism for array construction. An <code>xsl:array</code> instruction has 
                been proposed, and is prototyped as <code>saxon:array</code> in current Saxon releases; 
                but the difficulty is in defining the detail of how it should 
                work. It makes sense for it to enclose a sequence constructor, so instructions 
                like <code>xsl:for-each</code> and <code>xsl:choose</code> can be used when building the content. 
                But sequence constructors deliver sequences of items, not sequences of sequences.
                So the current proposal for <a href="https://qt4cg.org/branch/master/xslt-40/Overview.html#array-construction">XSLT 4.0</a>
                envisages an <code>xsl:array-member</code> instruction that wraps a sequence as a zero-arity
                function. The problem with this is that the mechanism is transparent yet arbitrary;
                it looks like (and is) a kludge.
            </p>
            <h2>Array Processing</h2>
            
            <p>Similarly, there are limited options for processing of arrays. There's no 
                equivalent of the "for" clause in FLWOR expressions that binds a variable 
                to each member of an array in turn. The closest things on offer are the 
                <code>array:filter()</code> and <code>array:for-each()</code> higher order functions – which are 
                more useful in XQuery than in XSLT, because of the difficulty in XSLT 
                of writing an anonymous function that constructs new XML element nodes. 
                XSLT in particular relies heavily (in constructs such as <code>xsl:apply-templates</code>, 
                <code>xsl:for-each</code>, <code>xsl:iterate</code>, and <code>xsl:for-each-group</code>) on binding values implicitly 
                to the context item. But the context item is an item, not an arbitrary value, 
                so binding members of arrays to the context item isn't an option.
            </p>
            <p>Generalizing "." to represent an arbitrary value rather than a single item seems 
                an attractive idea, but it's very hard to do without breaking a lot of existing code.
            </p>
            <p>Iterating over an array and binding each member to a variable works well in XQuery,
            where adding a "for member" clause to FLWOR expressions works cleanly enough. But there's
            lots of other functionality for processing sequences that can't be translated easily
            into equivalent mechanisms for arrays, especially in XSLT.</p>
        
            <h2>Parcels</h2>
            
            <p>It seems that a solution for both array construction and array processing is to find 
                a way to pack an arbitrary sequence into a single item. We'll refer to a "sequence 
                packed into an item" as a parcel. We can then construct an array from a sequence 
                of parcels, and we can decompose an array into a sequence of parcels, allowing 
                both operations to be implemented using all the existing machinery for handling 
                sequences. 
            </p>
            <p>It seems that four operations are sufficient to fill the processing gap:
            </p>
            <ul><li>Wrap a sequence as a parcel</li>
            <li>Unwrap a parcel as a sequence</li>
            <li>Construct an array from a sequence of parcels</li>
            <li>Decompose an array into a sequence of parcels</li>
            </ul>
            <p>So four functions should do the job: <code>parcel(item()*) =&gt; P</code>, 
                <code>unparcel(P) =&gt; item()*</code>, <code>array:of(P*) as array(*)</code>, <code>array:members(array(*)) as P*</code>, 
                where <code>P</code> is the item type of a parcel. Of course, we can also add XSLT or XQuery syntactic 
                sugar on top of these building blocks.
            </p>
            <p>We now have to address the question: what kind of item is a parcel? Is it represented using something we 
                already know and love (like an array, or a zero-arity function) or is it something new? How should 
                the type of a parcel be represented in type signatures, and what operations (apart from the above four) 
                should be available on them?
            </p>
            <p>I'm beginning to come to the conclusion that the type safety that comes from treating a parcel as a 
                new kind of item justifies the extra complexity in the type system. If we reuse an existing 
                kind of item (for example, zero-arity functions), then there's always going to be confusion about 
                whether items of that type are to be treated as parcels or as their "ordinary selves".
            </p>
            <p>However, I'm reluctant to add yet another fundamental type. We can't keep adding fundamental 
                types, and new syntax, every time we need something new (cf my Balisage 2020 paper on adding 
                promises). Can't we make the type system more extensible?
            </p>
            <p>Pro tem, I suggest we build on the concept of "extension objects" defined in §25.1.3 of 
                the XSLT specification. These are intended as opaque objects that can be returned by 
                one extension function and supplied to another. This concept should really be defined 
                in XDM rather than in XSLT. We should add that an "extension object" may be an instance 
                of an "extension type", and that extension types are denoted in the ItemType syntax by a 
                QName (that is, the same syntax as atomic types), with the QName being made known to the 
                processor in some implementation-defined way. Then we reserve a namespace URI sys for 
                "built in extension types", and define sys:parcel as such a type.
            </p>
            
    </div></content></entry><entry><title>Saxon-CS says Hello World</title><link href="https://blog.saxonica.com/mike/2021/03/saxon_cs_hello_world.html" rel="alternate" type="text/html"/><id>https://blog.saxonica.com/mike/2021/03/saxon_cs_hello_world.html</id><published>2021-03-22T10:34:00Z</published><content type="xhtml" xml:base="https://blog.saxonica.com/mike/2021/03/saxon_cs_hello_world.html"><div xmlns="http://www.w3.org/1999/xhtml">
        <p>The Saxon product on .NET has been living on borrowed time for a while.
        It's built by converting the Java bytecode of the Java product to the 
        equivalent .NET intermediate language, using the open-source IKVM converter
        produced by Jeroen Frijters. Jeroen after many years of devoted service
        decided to give up further development and maintenance of IKVM a few
        years ago, which didn't immediately matter because the product worked
        perfectly well. But then Microsoft in 2019 announced that future
        .NET developments would be based on .NET Core, and IKVM has never supported
        .NET Core, so we clearly had a problem.</p>
        <p>There's a team attempting to produce a fork of IKVM that supports
        the new .NET, but we've never felt we could put all our eggs in that basket.
        In any case, we also have performance problems with IKVM that we've never
        managed to resolve: some applications run 5 times slower than Java, and
        despite a lot of investigation, we've never worked out why.</p>
        <p>So we decided to try a new approach, namely Java-to-C# source code
        conversion. After a lot of work, we've now achieved successful compilation
        and execution of a subset of the the code, and for the first time this
        morning, Saxon-CS successfully ran the minimal "Hello World" query.</p>
        <p>We're a long way from having a product we can release, but we can now
        have confidence that this approach is going to be viable.</p>
        <p>How does the conversion work? We looked at some available tools,
        notably the product from Tangible Solutions, and this gave us many
        insights into what could be readily converted, and where the remaining
        difficulties lay; it also convinced us that we'd be better off writing
        our own converter.</p>
        <p>The basic workflow is:</p>
        <ol>
            <li>Using the open source JavaParser library, parse the Java code, generate
            an XML abstract syntax tree for each module, and annotate the syntax tree with type information
            where needed.</li>
            <li>Using XSLT code, do a cross-module analysis to determine which methods override each other,
            which have covariant return types, etc: information needed when generating the C# code.</li>
            <li>Perform an XSLT transformation on each module to generate C# code.</li>           
        </ol>
        <p>We can't convert everything automatically, so there's a range of strategies we use to
        deal with the remaining issues:</p>
        <ul>
            <li>Some constructs can simply be avoided. We have trouble, for example, converting
            Java method references like <code>Item::toString</code>, because it needs a fair bit of 
            context information to distinguish the various possible translations. But it's no great
            hardship to write the Java code a different way, for example as a lambda expression
            <code>item -&gt; item.toString()</code>. Another example is naming conflicts: C# doesn't
            allow you, for example, to have a variable with the same name as a method in the containing
            class. It's no hardship to rename the variables so the problem doesn't arise.</li>
            <li>We can use Java annotations to steer the conversion. For example, sometimes
            we want to generate C# code that's completely unrelated to the Java code. We can move
            this code into a method of its own, and then add an annotation <code>@CSharpReplaceMethodBody</code>
            which substitutes different code for the existing method body. The annotation is copied
            into the XML syntax tree by the JavaParser, and our converter can pick it up from there.</li>
            <li>We already have a preprocessor mechanism to mark chunks of code as being excluded from
            particular variants of the product (such as Saxon-HE or Saxon-PE). We can make further use
            of this mechanism. However, it's limited by the fact that the code, prior to preprocessing,
            must be valid Java so that it works in the IDE.</li>
        </ul>
        <p>The areas that have caused most trouble in conversion are:</p>
        <ul>
            <li>Inner classes. C# has no anonymous inner classes, and its named inner classes correspond
            only to Java's static inner classes. Guided by the way the Tangible converter handles these,
            we've found a way of translating them that handles most cases, and we've added Java annotations
            that provide the converter with extra information where additional complexities arise.</li>
            <li>Enumeration types. C#'s enumeration types are much more limited than the equivalent in
            Java, because enumeration constants can't have custom methods associated with them. We distinguish
            three kinds of enumeration classes: singleton enumerations (used to implement classes that will
            only have a single instance); simple enumerations with no custom behaviour, which can be translated
            to C# enumerations very directly, and more complex enumerations, that result in the generation
            of two separate C# classes, one to hold the enumeration constants, the other to accommodate the
            custom methods.</li>
            <li>Generics. C# is much stricter about generic types than Java, because the type information
            is carried through to run-time, whereas in Java it is used only for compile-time type checking,
            which can be subverted by use of casting. So the rule in C# is, either use generics properly,
            or don't use them at all. We anticipated some of these issues a year or two ago when we
            first started thinking about this project: see 
                <a href="/mike/2020/01/java-generics-revisited.html">Java Generics Revisited</a>.
            The result is that the classes representing XDM sequences and sequence iterators no longer use
            generics, which has saved a lot of hassle in this conversion. But there are still many
            problems, notably (a) the type inference needed to support Java's diamond operator (as in 
            <code>new ArrayList&lt;&gt;()</code>, where an explicit type parameter is needed in C#),
            and (b) the handling of covariant and contravariant wildcards (<code>? extends T</code>,
            <code>? super T</code>.)</li>
            <li>Iterators and enumerators. A <code>for-each</code> loop in Java (<code>for (X x : collection)</code>)
                relies on the <code>collection</code> operand implementing the <code>java.lang.Iterable</code>
                interface. To translate this into a C# for-each loop (<code>foreach (X x in collection)</code>)
                the <code>collection</code> needs to implement <code>IEnumerable</code>. So we convert
                all Iterables to IEnumerables, and that means we have to convert Iterators to Enumerators.
                Unfortunately Java's <code>Iterator</code> interface doesn't lend itself to static
                translation to a c# <code>IEnumerator</code>: in Java, the <code>hasNext()</code>
                method is stateless (so you can call it repeatedly), whereas C#'s <code>MoveNext</code>
                changes the current position (so you can't). We're fortunate that we only make
                modest use of Java iterators; in most of the code, we use Saxon's <code>SequenceIterator</code>
                interface in preferance, and this converts without trouble. We examined all the cases
                where Saxon explicitly uses <code>hasNext()</code> and <code>next()</code>, and made
                sure these followed the discipline of calling <code>hasNext()</code> exactly once
            before each call on <code>next()</code>; with this discipline, converting the calls to
            <code>MoveNext()</code> and <code>Current</code> works without problems.</li>
            <li>Lambda expressions and delegates. In Java, lambda expressions can be used where the
            expected type is a <i>functional interface</i>; a functional interface in other ways is just
            an ordinary interface, and you can have concrete classes that implement it. So for example
            the second argument of <code>NodeInfo.iterateAxis(axis, nodeTest)</code> is a <code>NodeTest</code>,
            for which we can supply either a lambda expression (such as <code>it -&gt; it instanceof XSLExpose</code>),
            or one of a whole range of implementation classes such as a <code>SchemaElementTest</code>,
            which tests whether an element belongs to an XSD-defined substitution group. In C#, lambda expressions
            can only be used when the expected type is a delegate, and if the expected type is a delegate,
            then (in effect) a lambda expression is the only thing you can supply. The way we've handled this
            is generally to make the main method (like <code>iterateAxis()</code> expect a non-delegate
            interface, and then to supply a proxy implementation of this interface that accepts a delegate.
            It's not a very satisfactory solution, but it works.</li>
            
        </ul>
        <p>One area where we could have had trouble, but avoided it, is in the use of the Java
        <code>CharSequence</code> class. I wrote about this issue last year at
            <a href="/mike/2020/07/string-charsequence-ikvm-and-net.html">String, 
                CharSequence, IKVM, and .NET</a>. As described in that article, we decided to eliminate
        our dependence on the <code>CharSequence</code> interface. For a great many internal uses of strings
        in Saxon, we now use a new interface <code>UnicodeString</code> which as the name implies is much
        more Unicode-friendly than Java's <code>String</code> and <code>CharSequence</code>. It also reduces
        memory usage, especially in the TinyTree. But there is a small overhead in the places where we
        have to convert strings to or from <code>UnicodeStrings</code>, which we can't hide entirely:
        it represents about 5% on the bottom line. But it does make all this code much easier to port
        between Java and C#.</p>
        
        <p>What about dependencies? So far we've just been tackling the Saxon-HE code base, and that has
        very few dependencies that have caused any difficulty. Most of the uses of standard Java library
        classes (maps, lists, input and output streams, and the like) are handled by the converter,
        simply translating calls into the nearest C# equivalent. In some cases such as <code>java.util.Properties</code>
        we've written en emulation of the Java interface (or the parts of it that we actually use). In other
        cases we've redirected calls to helper methods. For example we don't always have enough type
        information to know whether Java's <code>List.remove()</code> should be translated to
        <code>List.Remove()</code> or <code>List.RemoveAt()</code>; so instead we generate a call on
        a static helper method, which makes the decision at runtime based on the type of the
        supplied argument.</p>
        
        <p>The only external dependency we've picked up so far is for handling big decimal numbers.
        We're currently evaluating the <code>BigDecimal</code> library from Singulink, which appears
        to offer all the required functionality, though its philosophy is sufficiently different
        from the Java <code>BigDecimal</code> to make conversion non-trivial.</p>
        
        <p>One thing I should stress is that we haven't written a general purpose Java to C# converter.
            Our converter is designed to handle the Saxon codebase, and nothing else. Some of the
            conversion rules are specific to particular Saxon classes, and as a general principle,
            we only convert the subset of the language and of the class library that we actually need.
            Some of the conversion rules assume that the code is written to the coding conventions
            that we use in Saxon, but which might not be followed in other projects.</p>
        
        <p>So, Hello World to Saxon-CS. There's still a lot of work to do, but we've reached a significant
        milestone.</p>
        
    </div></content></entry><entry><title>The Zeno Chain: a new data structure for XDM sequences</title><link href="https://blog.saxonica.com/mike/2021/03/zeno_chains.html" rel="alternate" type="text/html"/><id>https://blog.saxonica.com/mike/2021/03/zeno_chains.html</id><published>2021-03-18T15:34:00Z</published><content type="xhtml" xml:base="https://blog.saxonica.com/mike/2021/03/zeno_chains.html"><div xmlns="http://www.w3.org/1999/xhtml">
        <p>This article presents the Zeno Chain, a new data structure used
        to underpin the implementation of XDM sequences in Saxon. It is also
        designed to be capable of supporting XDM arrays, and might also have
        potential for holding long character strings.</p>
        <p>The current implementation of the Zeno Chain is a mutable list,
        but the design lends itself easily to creating an immutable variant.
        It also makes it easy to construct an immutable list from a mutable
        one, making it efficient to construct a sequence with in-situ
        modification, and then "freeze" it once construction is complete.</p>
        <p>Saxon currently uses a variety of structures for holding sequences
        and arrays. This variety is a problem in itself. Choosing the right
        structure for a particular scenario involves somewhat hit-or-miss 
        decision making; it would be better to have a single "all-rounder"
        structure that performs well in a variety of situations.</p>
        <p>There are of course vast numbers of data structures for sequences
        available in the computer science literature. One promising one,
        for example, is the "finger tree" which supports a wide range of
        access patterns efficiently. But it also has drawbacks: any tree
        structure that requires a node for each item in a list is going
        to have a large memory overhead when storing a long sequence, and
        the use of a fine-grained structure like this tends to mean that
        there is little locality of reference for memory addressing, leading
        to poor CPU caching performance.</p>
        <p>The Zeno chain stores a sequence as a list of lists of items:
        that is, it is a tree with a constant depth of 2. In the Java
        implementation, both levels of list are instances of 
        <code>java.util.ArrayList</code>. The key to the performance of the
            structure is managing the number and size of the second-level
            lists, which I call <i>segments</i>.</p>
        <p>In a list that is constructed by appending individual items
            on the end (a common scenario), the length of a segment
            increases the closer it is to the start. For a list of 20,000
            items, there are ten segments whose sizes are (8192, 4096, 4096, 
            2048, 1024, 256, 128, 64, 64, 32). (Now you know why I called
            it a Zeno chain.) The exact numbers don't matter
            here: what is important is that the total number of segments
            increases only logarithmically with the length of the sequence,
            and that the segments on the right are short, which makes further
            append operations efficient.</p>
        <p>In a list constructed by prepending individual items, the
            distribution of lengths will be the other way round: shortest
            segments near the front. In the rare case where both append and
            prepend operations occur, both ends will have short segments,
            while longer segments will cluster around the middle.</p>
        <p>Here's a summary of the major operations performed on the sequence:</p>
        <ul>
            <li><b>Append an item:</b> if the list is empty, construct a single
            segment of length 1. Otherwise, if the last segment has length &lt; 32,
            append to it. If the last segment is already full, coalesce the last segment with the previous
            segment if the previous segment has sufficient room; if not, work
            up the list to the start to find adjacent segments that can be merged.
            A segment is considered to have sufficient room for such expansion if its resulting size
            would not exceed 2^(N+5) where N is the distance of the segment
            from the right-hand end of the sequence; it's this formula that ensures
            that longer segments accumulate at the start of the sequence. If all
            segments in the sequence are full — that is, if the
            segment sizes are decreasing powers of two — then add a new segment. 
            Append operations essentially take constant time; 97% of them only
            affect the final segment.</li>
            <li><b>Prepend an item:</b> simply append in reverse.</li>
            <li><b>Get the Nth item:</b> search the master list of segments examining
            the sizes of the segments until
            the right segment is found, then get the item by addressing into the
            Java <code>ArrayList</code>. This takes logarithmic time. The average
            access time will be slightly higher in a list built by prepending items,
            because the chance of finding the required item in the first couple of
            segments is much lower.</li>
            <li><b>Subsequence:</b> make a new Zeno chain containing whole or part copies
            of the segments from the original chain that are in the required range.</li>
            <li><b>Iteration:</b> Keep two index positions, the index position in the master
            list, and the index position in the current segment, and use these indexes
            to retrieve the next item by calling <code>ArrayList.get()</code> twice.</li>
            <li><b>Sequence concatenation: </b> This is quite a common operation in
            XSLT and XPath, as it's the basis of the "flattening" operations such as
            <code>xsl:for-each</code>, <code>xsl:apply-templates</code>, and
            FLWOR expressions. The most direct approach is simply to concatenate the two
            master lists, leaving the segments unchanged. This however can lead to 
            fragmentation of the sequence, so we perform a reorganization to
            reduce the number of short segments. Specifically, working from the
            right hand end, if any segment is found to be shorter than both its
            immediate neighbours, we combine it with the left-hand neighbour
            and reduce the number of segments by one. This has the effect of reducing
            the incidence of short segments in the middle of the chain.</li>
            <li><b>Insertion, removal, and replacement: </b> these operations
            are comparatively rare. With the immutable version of the structure,
            an alteration affecting one of the larger segments will require copying
            of everything else in that segment. This isn't ideal: but it's better
            than copying the entire sequence, which is what often happens today.
            And the use of the Java <code>ArrayList</code> at least means that the
            copying is very fast.</li>
        </ul>
        <p>It's important to note that most operations on sequences don't actually
            result in a new sequence being constructed. Calling <code>tail()</code>,
            for example, doesn't copy any data: it delivers an iterator over a portion
            of the original sequence. The sequence only gets materialized if, for example
            the result is stored in a variable (and even then, not always).</p>
        <p>Saxon's default implementation for a sequence is simply a Java List.
            Appending an item to a list generally copies the whole list. Where Saxon
            can detect that this is going to be inefficient, it instead uses a structure
            called a Chain: this is effectively a tree of segments. But there's little
            serious attempt to manage the depth of the tree or the size of the segments,
            and the results in some cases can be rather poor.The Zeno chain offers
            a signficant improvement; it also looks as if it can be used for arrays
            as well as sequences.</p>
        <p>For managing long strings, I invented a similar structure, which I then
            discovered already existed in the literature and is known as a Rope:
            a Rope represents a string as a tree of substrings. The literature on
            Ropes describes how to keep the tree balanced, but it has nothing to say
            about how to decide how many substrings to hold, and how long to make them.
            The Zeno chain might turn out to provide an answer to that question.

        </p>
    </div></content></entry><entry><title>Arrow Expressions</title><link href="https://blog.saxonica.com/mike/2020/11/19-arrow-expressions.html" rel="alternate" type="text/html"/><id>https://blog.saxonica.com/mike/2020/11/19-arrow-expressions.html</id><published>2020-11-19T10:20:00Z</published><content type="xhtml" xml:base="https://blog.saxonica.com/mike/2020/11/19-arrow-expressions.html"><div xmlns="http://www.w3.org/1999/xhtml">
    <h2>Arrow Expressions</h2>
    <p>When I proposed the arrow operator to the XQuery/XSLT working groups, I thought of it as minor syntactic sugar.
    It's just a convenience: instead of <code>substring-before(substring-after(X, '['), ']')</code> you can write
    <code>X =&gt; substring-after('[') =&gt; substring-before(']')</code> which helps you to avoid going cross-eyed.
    If you're the kind of person who can play the piano with your hands crossed over, you probably don't need it,
    but for the rest of us, it makes life just a tiny bit easier.</p>
    <p>So I was a bit surprised at XML Prague 2020 that Juri Leino managed to construct an entire
            presentation around the arrow operator 
            (<a href="https://speakerdeck.com/minuso/shooting-arrows-fast-and-accurately">Shooting Arrows Fast and Accurately</a>).
          Not only that, he also developed a whole library of functions, called XBow, to increase their power.</p>
    <p>Now, XBow actually reveals a bit of a weakness in the construct: you can construct a pipeline of functions,
          but you can't include arbitrary expressions in the pipeline unless each of the expressions is made available
          via a function. Moreover,
          the value output by one step in the pipeline can only be used as the first argument in the next function: you
          can do <code>X =&gt; concat('$')</code> to add a "$" at the end of a string, but there's no simple way of adding
          a "$" at the front, except by defining a new <code>prepend</code> function that does this for you (or hoping
            that XBow will have anticipated your requirement).</p>
    <p>Now, of course you can do <code>X ! concat('$', .)</code>. But that doesn't always fit the bill. Firstly,
          it only works when you're processing single items (or mapping a sequence to multiple items). Secondly,
          (to use the current jargon) the optics are wrong: it breaks the pipeline visually.</p>
    <p>So my first suggestion is that we allow inline expressions to appear in a pipeline. Something like this:
          <code>X =&gt; {~ + 1}</code>, or <code>X =&gt; {concat('$', ~)}</code>. 
            I'm using '~' here as a variable to refer to the
          implicit argument, that is, the value passed down the pipeline. I would have used '_', as Scala does, but unfortunately
          '_' is a legal element name so it already has a meaning. And '~' seems to work quite nicely.</p>
    <p>The next thing that's been requested is implicit mapping, so you can use something like arrow notation
          to do <code>X ! substring-after(., '$') ! number(.) =&gt; sum()</code>. (Actually, the main obstacle in getting
          the arrow operator accepted by the XQuery Working Group was that some people wanted it to have this meaning.)</p>
    <p>For that I propose we use a "thin arrow": <code>X -&gt; substring-after('$') -&gt; number() =&gt; sum()</code>.
          The effect of the thin arrow is that instead of passing the value of the LHS to the function on the RHS
          <i>en bloc</i>, we pass it one item at a time. Of course, if the value on the LHS is a single item, then
          it doesn't matter which kind of arrow we use, both have the same effect.</p>
    <p>If you're a fan of map-reduce terminology, then you'll recognize this instantly as a map-reduce
          pipeline. The <code>-&gt;</code> operations are doing a mapping, and the final <code>=&gt;</code> does a reduce.
            If you're more into functional thinking, you probably think of it more in terms of function composition.</p>
    <p>Of course thin arrows can also be used with arbitrary expressions, just like thick arrows:
          <code>(0 to 3) -&gt; {~ + 1} -&gt; format-integer('a') =&gt; string-join('.')</code> returns 
            <code>"a.b.c.d"</code>.</p>
    <p>And now I'd like to pull one more rabbit out of the hat. What if I want a function that applies the
            above pipeline to any input sequence. I could write <code>function($x){$x -&gt; {~ + 1} -&gt; 
              format-integer('a') =&gt; string-join('.')}</code> but that seems clunky. I'm looking for a nice way
          to supply functions as arguments to higher-order functions like sort, where other languages have
          shown that a concise notation for anonymous functions (like <code>a -&gt; a+1</code> in Javascript) can
          make code a lot simpler, less verbose, more readable.</p>
    <p>So my proposal is this: just remove the left-hand expression, so you have something starting with
          <code>-&gt;</code> or <code>=&gt;</code>, and use this as an anonymous arity-1 function.</p>
    <p>So you can now do: <code>//employee =&gt; sort((), -&gt;{~/@salary})</code> to sort employees
            by salary, or <code>//employee =&gt; sort((), -&gt;{~/@salary}-&gt;substring-after('$')-&gt;number())</code> 
          if you need to do a bit more processing.</p>
    <p>As another little refinement, in the case of <code>-&gt;</code>, the implicit argument is
          always a single item, so we can bind it to the context item. So <code>-&gt;{~/@salary}</code>
          can be simplified to <code>-&gt;{@salary}</code>. Basically, within curly braces on the RHS of <code>-&gt;</code>,
          <code>.</code> and <code>~</code> mean the same thing.</p>
    <p>I believe that all these constructs can be added to the grammar without introducing ambiguity
          or backwards incompatibility, but I haven't proved it conclusively yet.</p>
    <h3>Postscript</h3>
    <p>The <code>~</code> construct seems to be the missing ingredient to enabling pipelines in XSLT.
          Consider:</p>
    <p><pre>
&lt;xsl:pipeline&gt;
  &lt;xsl:apply-templates select="/" mode="m1"/&gt;
  &lt;xsl:apply-templates select="~" mode="m2"/&gt;
  &lt;xsl:for-each select="~"&gt;
    &lt;e&gt;&lt;xsl:copy-of select="."/&gt;&lt;e&gt;
  &lt;/xsl:for-each&gt;
&lt;/xsl:pipeline&gt;             
            </pre></p>
    <p>Here "~" is acting as an implicit variable to pass the result of one instruction to be the input for
          the next: basically eliminating the clunky <code>xsl:variable</code> declarations needed to do this today.
          The instructions that form the children of the <code>xsl:pipeline</code> element are effectively
          connected to each other with an implicit <code>=&gt;</code> operator.</p>
  </div></content></entry><entry><title>Draft Proposals for XSLT/XPath/XQuery 4.0</title><link href="https://blog.saxonica.com/mike/2020/11/14-qt40-proposal-comments.html" rel="alternate" type="text/html"/><id>https://blog.saxonica.com/mike/2020/11/14-qt40-proposal-comments.html</id><published>2020-11-14T19:19:00Z</published><content type="xhtml" xml:base="https://blog.saxonica.com/mike/2020/11/14-qt40-proposal-comments.html"><div xmlns="http://www.w3.org/1999/xhtml">

      <h2>Draft Proposals for XSLT/XPath/XQuery 4.0</h2>

    
    <p>I've been working on translating the ideas in my XML Prague 2020 paper, 
      entitled <a href="https://www.saxonica.com/papers/xmlprague-2020mhk.pdf">a Proposal for XSLT 4.0</a> into concrete specifications, and my first attempt at this can be found
    here:</p>
    
    <p>
      I'm hoping to gather together a community group of some kind to take this forward; meanwhile I've published a very preliminary set of drafts:
      </p>
    <ul>
      <li><a href="https://www.saxonica.com/qt4specs/XT/Overview-diff.html">XSLT</a></li>
      <li><a href="https://www.saxonica.com/qt4specs/FO/Overview-diff.html">Functions and Operators</a></li>
      <li><a href="https://www.saxonica.com/qt4specs/XP/xpath-40-diff.html">XPath</a></li>
      <li><a href="https://www.saxonica.com/qt4specs/XQ/xquery-40-diff.html">XQuery</a></li>
      </ul>

    
    <p>I put these ideas up yesterday on the XML community Slack channel and got some great feedback.
    Unfortunately Slack isn't really a good vehicle for managing the response to this feedback. I'm
    going to organise some GitHub space for a more structured discussion, but meanwhile, here
    are my reactions to the initial comments:</p>
    
    <h3>Phil Fearon:</h3>
    <p>There’s a lot to digest here so hope to provide feedback after I’ve read this more thoroughly.
    One suggestion (inspired by ReactJS/JSX) is to provide some syntactical sugar for <code>xsl:call-template</code>. 
    So a call to a named template appears more like a literal result element (perhaps with a special namespace), 
    with attributes that correspond to template params. This could also allow the child items of the special-LRE 
    to be passed to the named template, accessed via a special $children param.
    </p>
    <p><i>Yes, I've been wanting to do something like this for years, and it's really not difficult, so I've
    added it. If EX is listed in <code>extension-element-prefixes</code>, and if there's a named template
      <code>name="ex:action"</code>, then <code>&lt;ex:action a="expr" b="expr"/&gt;</code> is interpreted
    as an <code>xsl:call-template</code> with <code>xsl:wth-param</code> children for parameters <code>a</code> and
    <code>b</code>.</i></p>
    
    <h3>Liam Quin</h3>
    <p>first quick note, best NOT to have them say W3C Recommendation on them as this may cause confusion.</p>
    <p><i>Yes, sorry about that, still working my way around the stylesheets that generate the boilerplate text...</i></p>
    
    <p>2d, cam xsl:text have a select attribute? i don't think value-of can be deprecated :disappointed: 
      but xsl:text select= would be consistent &amp; may help.</p>
    
    <p><i>It's one of these things that one would like to simplify, but we can only add things not remove them,
    so that's not easy.</i></p>
    <p>" the tunnel parameters that are implicitly passed in a template call may have names that duplicate 
      the names of non-tunnel parameters that are explicitly passed on the same call." is a major source 
      of difficult debugging if you forget tunnel=yes. Maybe the answer is just a warning from impl'ns.
    </p>
    
    <p><i>Yes. How to solve this without breaking compatibility? Perhaps a dynamic error if you declare a non-tunnel
    parameter, and at run-time there's a tunnel parameter with that name, but no non-tunnel parameter, or vice versa?
    Or, as you say, just rely on warnings. I agree it's a very common mistake that's hard to debug.</i></p>
    <p>The "at $pos" of XQuery is super useful. position() is tricksy.Maybe for-each at="name" ?</p>
    <p><i>In 3.0 we experimented with replacing some of the context functions with explicit variable bindings
    and it got a bit messy, but I think it's a shame we didn't persevere. The toughest one is <code>last()</code>,
    it would be awfully nice if we knew statically whether <code>last()</code> was going to be needed or not,
    but again, hard to fix without breaking code.</i></p>
    
    <p>prefix binding didn't make the cut for XPath?</p>
    <p><i>I did a design for this and didn't like it enough to put it in. I'll try again.</i></p>
    <p>item-at() seems not much easier than $xxx ! let $p := position() return $yyy[$p]</p>
    <p><i>I'm toying now with an alternative to item-at() that's much more powerful: slice(sequence, positions)
      so you can do <code>slice($s, 5)</code> or <code>slice($s, 5 to 10)</code> or 
      <code>slice($s, -1)</code> or <code>slice($s, 1 by 3 to count($s))</code> or
      <code>slice($s, -2 by -1 to -count($s))</code>. Here <code>A by B to C</code> is an extension
    of the current range expression where <code>A to B</code> means <code>A by 1 to B</code>.</i></p>
    <p>replace-with() seems like perl's e flag (JS has one too) but alas  no polymorphism so can't 
    write replace(., $expr, myfunc#1m 'e')</p>
    However,  what about adding a map or an array of  matching subgroups? ".{$2 || $1 * 2 || $2}"
    <p><i>Yes, I think it's a really useful capability, but I think it's cleaner to make it a separate function.
    Have to think about how subgroups might work.</i></p>
    
    <h3>Reece H. Dunn </h3>
    <p>I like the enum(...) syntax in addition to the union(...) syntax.</p>
    
    
    <p>I like the extension of element and attribute type tests to be full name tests. 
    The ability to define types for path expressions like (ol|ul) is missing, though.</p>
    
    <p><i>Yes, I'm in two minds whether union(X, Y, Z) should be restricted to a union of atomic types,
    or whether it should allow a union of any types including node types. Orthogonality suggests the latter,
    but I was too timid to propose that.</i></p>
    
    
    <p>For named item types, is it possible to make them available as part of the in-scope schema types 
    (renamed to in-scope types that would include the schema and named types?), so you could say 
    person-name instead of item-type(person-name). -- Having to qualify the named item types everywhere 
    could get too verbose, especially if the name is short. _NOTE:_ This is done for MarkLogic types 
    where you can refer to map:map, cts:query, etc.</p>
    
    <p><i>Interesting idea. There's obviously a need to resolve conflicts but that's not a stopper.
    I think I was more concerned with the idea that if it's a QName then it must be atomic, and the
    messy fact that the sets of schema types and item types overlap, and the overlap contains all atomic types
    and some but not all union types.</i></p>
    
    <h3>Liam Quin</h3> 
    <p>hmm, xsl:sequence could do with an "as" attribute.</p>
    <p><i>Not convinced. You start wanting to put it anywhere e.g. on xsl:if or xsl:apply-templates.</i></p>
    
    
    
    <h3>Reece H. Dunn</h3>
    <p>In https://www.saxonica.com/qt4specs/XP/xpath-40-diff.html#id-itemtype-subtype, 
    rule 2(d) is missing the reference to the EnumerationType symbol ("A is an ," instead of "A is an EnumerationType,").</p>
    
    <p><i>Stylesheet trouble. The XSLT and XPath spec stylesheets have diverged, the XSLT spec allows 
      <code>&lt;termref def="some-term"/&gt;</code> and picks up the term from the definition, but 
      the XPath spec requires <code>&lt;termref def="some-term"&gt;term&lt;/termref&gt;</code>. I need to bring them
    back into line. Applies to your subsequent comments also.</i></p>
    
    
    <h3>Martin Honnen</h3>
    <p>I like the separator attribute on xsl:apply-templates and xsl:for-each. 
    I wonder whether it would make sense to add it to xsl:for-each-group as well.</p>
    
    <p><i>Yes. Also xsl:for-each-member. I'm not sure whether it should be an AVT or a general expression:
    with a general expression you could insert <code>br</code> or <code>hr</code> separators, especially if we have element constructor
    functions in XPath (<code>separator="build:element('hr')"</code>)</i> </p>
    
 
    <h3>Liam Quin</h3>  9 hours ago
    <p>i've been wondering abut the possibility of an xsl:uri-resolver for some time. </p>
    <p><i>Not sure what it would do?</i></p>
    <p>Also  about xsl:mode elements being able to contain xsl:template elements.</p>
    <p><i>Yes, I've wanted that for a long time. To be honest, it's not in 3.0 because I couldn't convince Sharon.</i></p>
    
    <h3>Reece H. Dunn</h3> 
    <p>The changes for XPath/XQuery look good. I see you changed the syntax for the context item and lambda syntaxes 
    to a unified syntax. I like that the concise and full syntaxes are now consistent.</p>
    
    
    <p>Given that . is allowed in a ParamList, does that mean I can now define a function that works on the path context item? For example:
    declare function local:f(.) { xs:integer(.) + 2 };
    //values/local:f()</p>
    
    <p><i>Actually, allowing "." here was an oversight caused by my changing the way the grammar rules worked.
    But there might be some benefit it keeping it.</i></p>
    
    <p>... does that mean that the context-dependent functions in F&amp;O should be defined using that syntax. For example:
    fn:data(.) as xs:anyAtomicType*</p>
    
    <p><i>I hadn't thought of baking the "implicit . as parameter" convention into the language, but it might make sense
    if it can be done.</i></p>
    
    <h3>Liam Quin</h3> 
    <p>in XQuery i don't understand "The for evaluation of the function body is absent, 
    unless the signature uses the "." notation, in which case it is evaluated with a singleton 
    focus bound to the supplied argument value."</p>
    <p><i>Markup trouble again.</i></p>
    
 
    <h3>Martin Honnen</h3>  9 hours ago
    <p>If xsl:for-each has a separator attribute, wouldn't xsl:for-each-member benefit from it as well?</p>
    <p><i>Yes, see above.</i></p>
    
    <h3>Reece H. Dunn</h3>  9 hours ago
    <p>For the schema import in XQuery, would it make sense to have:
    [22]    	SchemaPrefix 	   ::=    	("namespace" NCName "=") | ("default" ("element" | "type") "namespace")
    now that the element and type namespaces are separate, similar to how DefaultNamespaceDecl has changed.</p>
    
    <p><i>I thought about this and decided not. If you want finer control, use multiple declarations.</i></p>
    

    <p>For parameter lists and context items, would it be more useful to have the context item as an optional first parameter? That would mirror the proposed variadic argument syntax (defined for arguments at the end of the parameter list), and would allow arguments to be passed to the function, such as:
    declare function local:add(., $n) { xs:integer(.) + $n };
    //values/local:add(2)</p>
    
    <p><i>I quite like that in principle. Needs more thought.</i></p>
    
    Reece H. Dunn  9 hours ago
    <p>Is there any description of the arity of context item based functions? -- There should be a note or something similar to say that the context item for a function definition or inline function expression does not count to its arity, so function () and function (.) both have an arity of 0.
    </p>
    
    <p><i>I was thinking of them simply as arity-1 functions, suitable for callbacks in things like fn:filter and fn:sort.
    You're opening up new possibilities which I need to ponder.</i></p>
    <h3>line0 </h3> 
    <p>Great to see the spec coming to light!</p>
    <p>I proposed to add two new signatures to for-each</p>
    <p>for-each(item()*, function (item(), xs:positiveInteger) as item()*) as item()*</p>
    <p>for-each(item()*, function (item(), xs:positiveInteger, item()*) as item()*) as item()*</p>
    
    <p><i>I've proposed that the function coercion rules should allow you to supply an arity-1 function where
    an arity-2 function appears in the signature; so we can extend fn:for-each to take a <code>function(item, integer)</code>
    as the predicate callback, and you can still supply <code>function(item)</code> if you don't care about the position.</i></p>
    
    <p>which would bring for-each on par with FLOWR expressions ( for window and for … in … at ).</p>
    <p><i>It would be great to see windowing done with higher-order functions, but it's a significant piece of design
    and not my top priority - even though it would bring XSLT up to the level of XQuery for this kind of functionality.</i></p>
    
    
    
    <h3>Martin Honnen </h3> 
    <p>For fn:transform, Saxon has already added the option source-location as that is needed 
    to use fn:transform with streaming; I think it makes sense to integrate that option into the fn:transform specification of the FO 4 draft.
    </p>
    <p><i>Good point.</i></p>
    
  </div></content></entry><entry><title>XSLT Update – Some Ideas</title><link href="https://blog.saxonica.com/mike/2020/10/29-xslt_update_some_ideas.html" rel="alternate" type="text/html"/><id>https://blog.saxonica.com/mike/2020/10/29-xslt_update_some_ideas.html</id><published>2020-10-29T16:19:00Z</published><content type="xhtml" xml:base="https://blog.saxonica.com/mike/2020/10/29-xslt_update_some_ideas.html"><div xmlns="http://www.w3.org/1999/xhtml">
    <h1>XSLT Update – Some Ideas</h1>
    <p>I can't help feeling that many simple transformations on XML documents could be expressed more simply (an idea I explored with the interactive Gizmo tool available in Saxon 10).</p>
    <p>I also think that if we had simpler syntax for simple operations, it might become easier to optimise. In particular, I'd like to be able to do simple operations like adding an attribute to the outermost element of a tree without doing a physical copy of the entire tree.
      (I wrote about that in an <a href="https://www.saxonica.com/papers/xmlprague-2018mhk.pdf">XML Prague paper</a>, but I had to abandon the idea because the code became too complicated. As often happens, the bugbear was namespaces. For example, if you add a namespaced attribute to the outermost element, then the new namespace declaration has to propagate all the way down the tree.)</p>
    <p>I'd also like to see transformations on JSON structures (maps and arrays) become much easier.</p>
    <p>I've prototyped these ideas in the <a href="https://www.saxonica.com/documentation/index.html#!extensions/instructions/deep-update">saxon:deep-update</a>
      and <a href="https://www.saxonica.com/documentation/index.html#!extensions/instructions/update">saxon:update</a> extensions,
      but I don't think these are the last word on the subject. (Please try them and give feedback.)</p>
    <p>A simpler update syntax might also be very useful for updating the HTML page in Saxon-JS.</p>
    <p>I think we can pick up ideas from XQuery Update, but without the complications of pending update lists and in-situ modification.</p>
    <p>Let's start with:</p>
    <pre><code>&lt;xsl:update&gt;
   &lt;xsl:delete match="note"/&gt;
&lt;/xsl:update&gt;
</code></pre>
    <p>The idea is that <code>xsl:update</code> is an instruction that returns a deep copy of the context item (or other selected item if there's a select attribute), applying changes defined by the contained rules. In this case there is one rule, to delete elements that match the pattern note.</p>
    <p>So it's rather like the <code>copy-modify</code> instruction in XQuery; it makes a copy of a supplied tree, with
    defined changes.</p>
    <p>Other rules that might appear within <code>&lt;xsl:update&gt;</code> (for updating XML) might include:</p>
    <pre><code>&lt;xsl:rename match="note" name="comment"/&gt;
&lt;xsl:rename match="a:*" name="{local-name()}"/&gt;
&lt;xsl:replace-value match="@status" value="accepted"/&gt;
&lt;xsl:add-attribute match="proposal(not(@status))" name="status" value="accepted"/&gt;
&lt;xsl:replace-content match="cite[@ref]" select="//bib[@id=current()/@ref]"/&gt;
&lt;xsl:insert match="section(not(head))" position="first"&gt;
   &lt;head&gt;{@title}&lt;/head&gt;
&lt;/xsl:insert&gt;   
</code></pre>
    <p>Hopefully the intent is reasonably intuitive. The idea is to base the primitives on those available in XQuery Update.
    However, I'm not proposing to allow flow-of-control structures such as conditionals and function calls: each invocation
    of <code>xsl:update</code> will simply process the selected tree recursively, applying matching rules to nodes as they
    are found, based on pattern matching.</p>
    <h2>Defining the semantics</h2>
    <p>We can define the semantics of <code>&lt;xsl:update&gt;</code> as being equivalent to <code>&lt;xsl:apply-templates&gt;</code> using a mode that contains a number of implicit template rules, with a default action of <code>shallow-copy</code> (but extended to handle maps and arrays, see below).</p>
    <p>For example, the implicit template rule for the <code>&lt;xsl:rename&gt;</code> rule might be (roughly):</p>
    <pre><code>&lt;xsl:template match="note"&gt;
  &lt;xsl:element name="comment"&gt;
    &lt;xsl:apply-templates select="@*, node()"/&gt;
  &lt;/xsl:element&gt;
&lt;/xsl:template&gt;
</code></pre>
    <p>Now, what if there's a rule to rename an element and another rule to add an attribute to the same element?</p>
    <p>The way XQuery Update handles that is to process the rules in a number of phases: for example <code>rename</code> operations are handled in phase 1, <code>delete</code> operations in phase 5.</p>
    <p>It's a bit hard to replicate that behaviour using template rules (in fact, this is something users often ask for). We could run a multiphase transformation using multiple modes, but it's not quite the same thing, because the match patterns would apply to the output of the previous phase, not to the original node in the input. And <code>xsl:next-match</code> doesn't do the job either, because we want the effect of the rules to be cumulative.</p>
    <p>We could try another approach, which is to have the template rules return functions, so the <code>&lt;xsl:rename&gt;</code> rule becomes:</p>
    <pre><code>&lt;xsl:template match="note" priority="1"&gt;
  &lt;xsl:sequence select="function($x) {upd:rename($x, 'comment')}"/&gt;
  &lt;xsl:next-match/&gt;  
&lt;/xsl:template&gt;
</code></pre>
    <p>so the effect of <code>apply-templates</code> is to return a sequence of functions (in the order determined by the <code>priority</code> attributes) which are then applied to the node in turn.</p>
    <p>This still doesn't exactly mirror what XQuery Update does, because after processing a node, it's then going to apply the rules to the new content of the node, not to the old content. But perhaps that actually makes more sense?</p>
    <h2>Implementation</h2>
    <p>Part of the aim is not just to have simpler syntax for the user, but also to make the implementation more efficient than the standard transformation approach which always involves physical copying of a tree, no matter how small the changes.</p>
    <p>What I want to achieve is to have a data structure, rather like the HashTrie that we use for representing XDM maps, in which changing one entry doesn't involve copying the whole tree, but at the same time leaves the original value intact. The first essential for such a structure is that it doesn't contain parent pointers: instead upwards navigation is achieved by remembering, when we get to a node, how we got there: this means the same node can be reached by multiple routes, allowing subtrees to be shared between different trees.</p>
    <p>Suppose we are changing the value of a single attribute. It ought to be possible to achieve this by the following steps:</p>
    <ul>
      <li>Find the element we are modifying, remembering the ancestor path of that element.</li>
      <li>Create a "virtual copy" of this element (we already have this capability in Saxon)</li>
      <li>Modify the virtual copy to add the attribute. Only one element is affected; the descendant tree of the virtual copy is shared with the original tree.</li>
      <li>Work back through the ancestors; for each one, create a copy in which the affected child is replaced with the modified child, and all other children are virtual copies of the original.</li>
      <li>Return the copied root node.</li>
    </ul>
    <p>I'm hoping that it will be a lot easier to achieve this with the new syntax than it is with the current processing model, where we have to deal with all kinds of messiness like namespace inheritance. For example, we can define the new syntax so that it's equivalent to <code>inherit-namespaces="no"</code>.</p>
    <h2>What about JSON?</h2>
    <p>I would like this mechanism to work just as well with JSON trees (that is, structures of maps and arrays) as with XML trees.</p>
    <p>We're starting with some advantages: these structures don't have so much baggage. There's no node identity to worry about, no parent navigation, no namespaces. Also, the implementation data structures that we use for maps and arrays already allow efficient constant-time update.</p>
    <p>I've experimented with mechanisms for deep update of a JSON structure with extension functions such as <code>[saxon:pedigree()](https://www.saxonica.com/documentation/index.html#!functions/saxon/with-pedigree)</code>. and <code>saxon:with-pedigree()</code>. That's not exactly usable. But it might be the right primitive to implement something more usable.</p>
    <p>I've also proposed better pattern syntax for maps and arrays. For example, <code>match="tuple(first, last, *)"</code> matches any map that has entries with keys "first" and "last".</p>
    <p>One problem with using the XSLT recursive-descent approach for maps and arrays is that map entries (and indeed array members) aren't actually items. You can match a map as a whole, but it's hard to match one of its entries on its own. Again, I've experimented with various approaches to this. I think the introduction of tuples may help with this: we can define the recursive-descent operation on maps to process (match) each entry in the map in turn, where the entry is presented and matched as a tuple containing key and value. And then we allow syntax such as <code>match="tuple(key: keyPattern, value: valuePattern)"</code> to match these entries.</p>
    <p>But perhaps we don't need to expose this. Perhaps we can define a good enough set of primitive actions that match at the level of the map itself, for example:</p>
    <pre><code>&lt;xsl:remove-entry match="tuple(first, last, *)" key="'salary"/&gt;
&lt;xsl:replace-entry match="tuple(product-code, *) key="'price'" value="?price * 1.05"/&gt;
&lt;xsl:add-entry match="tuple(x, y, *)" key="'area'" value="?x * ?y"/&gt;
</code></pre>
    <p>I think this could fly: but there's a lot of detail to be worked out. Shame we don't have a WG any more to bounce ideas off (and get the bugs out).</p>
  </div></content></entry><entry><title>String, CharSequence, IKVM, and .NET</title><link href="https://blog.saxonica.com/mike/2020/07/string-charsequence-ikvm-and-net.html" rel="alternate" type="text/html"/><id>https://blog.saxonica.com/mike/2020/07/string-charsequence-ikvm-and-net.html</id><published>2020-07-20T09:06:54Z</published><content type="xhtml" xml:base="https://blog.saxonica.com/mike/2020/07/string-charsequence-ikvm-and-net.html"><div xmlns="http://www.w3.org/1999/xhtml">
      
      <p>A couple of years ago Jeroen Frijters announced that he would no longer be working
         on new IKVM developments (IKVM is the technology we use to make Saxon, which is written
         in Java, run on .NET). At one level that's not a problem: the tool works brilliantly
         and we can continue to use it. However, it doesn't support .NET Core, and Microsoft
         have announced that .NET 5 will be based on .NET Core, so that creates the risk that
         Saxon on .NET will hit a brick wall.</p>
      <p>Various smart people are working on trying to pick up IKVM where Jeroen left off,
         but I don't particularly want to bet the business on them being successful. Jeroen
         produced brilliant software but he left very little in the way of documentation or
         test material, so it's a hard act to follow.</p>
      <p>Meanwhile Microsoft seem to be back-pedalling on their original promise that .NET
         5 would support Java interoperability. They've never given any indication of how it
         would do so, despite much speculation.</p>
      <p>So we've been looking at alternative ways of taking Saxon on .NET forward into the
         future, and one of those is source code conversion. I've been looking at tools such
         as Tangible, which does a good job to a degree: they don't tackle the difficult parts
         of the problem where Java and C# are most different, but they give a very good insight
         into understanding what the difficult parts of the problem are going to be.</p>
      <p>And one of those difficult parts, which I'm focussing on at the moment, is the <b>CharSequence</b> problem. CharSequence is a Java interface that we use very extensively, and there's
         no equivalent on .NET. Unlike other dependencies on Java classes and interfaces, this
         one is impossible to emulate directly, because java.lang.String implements CharSequence,
         and there's no way we can make System.String on .NET do the same.</p>
      <p>The reason we use CharSequence, as with any interface, is so that we can have multiple
         implementations with different performance characteristics. To take a simple example,
         one of our implementations is CompressedWhitespace. A great deal of the text in an
         XML document is made up of whitespace, which sadly cannot be killed at birth: using
         a customised representation for strings that contain only whitespace gives a significant
         space saving. (And space savings also turn into speed improvements, given that execution
         time these days is dominated by how long it takes to get data in and out of the CPU's
         internal cache).</p>
      <p>Given that CharSequence has no equivalent on .NET, it occurred to me to ask how IKVM
         deals with it. Although Jeroen never wrote much documentaton, he did write a lot of
         blog posts about interesting design problems, and sure enough it seems that he gave
         this a lot of attention back in 2003 (how time flies when you're having fun). I thought
         that he might use an implementation of CharSequence that wraps a System.String, but
         it seems he rejected that approach in favour of a mechanism of what he calls "ghost
         interfaces". There's a lot of detail, but the bottom line seems to be that the code:</p>
      <pre><code>CharSequence seq = "foo";
seq.charAt(1);</code></pre>
      <p>is compiled to .NET as:</p>
      <pre><code>System.Object seq = "foo";
if(seq instanceof System.String)
  ((System.String)seq).charAt(1);
else if(seq instanceof CharSequence)
  ((CharSequence)seq).charAt(1);
else
  throw new IncompatibleClassChangeError()</code></pre>
      <p>That looks pretty horrifying, and I've belatedly realised that it could account for
         a lot of our observations on .NET performance over the years.</p>
      <p>When we first built Saxon on .NET, the performance overhead compared with Java was
         around 30%, which was quite acceptable. In recent years we've seen it getting worse,
         with some workloads showing a 300% slow-down, and despite considerable effort we've
         been at a loss to explain why. Synthetic benchmarks on IKVM continued to show a 30%
         overhead, but for Saxon the figure was far worse. We looked hard without success to
         find a hot-spot, something we were doing that IKVM handled particularly badly, but
         the slow-down seemed to be right across the board. I'm now prepared to conjecture
         that it's all down to our use of CharSequence - because CharSequence.charAt() is something
         we do very extensively, throughout the product.</p>
      <p>When data arrives in Saxon from a SAX parser, the content of text nodes arrives in
         char[] arrays, while the content of attributes arrives in String objects. And we keep
         it that way: in the TinyTree, text nodes are effectively slices of a char[] array,
         and attributes are Strings. All the operations that we perform on text, including
         performance-critical operations such as equality matching, sorting, and string-to-number
         conversion, therefore need to work on either representation, and that's essentially
         why we use CharSequence. In general, we don't want to spend time converting data between
         different representations so we can perform different operations on it. </p>
      <p>(In recent releases, though, we've started using a different representation for operations
         where we need to count Unicode codepoints rather than UTF-16 chars. For regular expressions,
         and some other operations such as translate(), we first convert the string to a UnicodeString,
         which is our own interface that supports direct codepoint addressing, with internal
         implementations using 8, 16, or 32 bits per character depending on the widest character
         present in the string).</p>
      <p>So if CharSequence is a problem, what should we do instead? Is there any other way
         we can implement operations such as collation comparison and string-to-number conversion
         efficiently without first converting the data to a common internal format?</p>
      <p>I think part of the solution might be for these operations to be written to use codepoint
         iterators. Iterating over a string using an IntIterator that delivers codepoints is
         probably just as efficient as using a for-loop with charAt(), and it's possible to
         create an IntIterator over any string representation efficiently (meaning, without
         copying the actual characters).</p>
      <p>This suggests the following broad approach:</p>
      <p>(a) For attributes, continue to use Strings</p>
      <p>(b) For text nodes on the Receiver pipeline and in the TinyTree, use an interface
         similar to CharSequence - let's call it UniString - that allows multiple implementations,
         but that doesn't have the magic property that String can be used directly as an implementation.
         (Instead, there will be an implementation of UniString that wraps a String).</p>
      <p>(c) For operations on strings and string-like values, use a codepoint iterator wherever
         possible.</p>
      <p>This is a gross simplification: we're dealing with half a million lines of code that's
         all concerned with string handling, so the detail is horrendous. But having a simplified
         description of the problem and the solution helps greatly when you're hacking through
         the jungle.</p>
   </div></content></entry><entry><title>The Java class hierarchy for XPath type objects</title><link href="https://blog.saxonica.com/mike/2020/02/the-java-class-hierarchy-for-xpath-type-objects.html" rel="alternate" type="text/html"/><id>https://blog.saxonica.com/mike/2020/02/the-java-class-hierarchy-for-xpath-type-objects.html</id><published>2020-02-10T11:26:47Z</published><content type="xhtml" xml:base="https://blog.saxonica.com/mike/2020/02/the-java-class-hierarchy-for-xpath-type-objects.html"><div xmlns="http://www.w3.org/1999/xhtml">
      
      <p>The set of interfaces and classes used in the Java code to represent XSD and XDM types
         has become something of a nightmare. This article is an attempt to explain it. When
         you don't understand something well, you can often improve your understanding by trying
         to explain it to others, so that's what I shall attempt to do.
         </p>
      <p>
         The first complication is that we have to model schema types and item types, and these
         are overlapping categories.
         </p>
      <p>
         Schema types - types as the term is used in XSD - are either simple types or complex
         types; simple types are either atomic types, union types, or list types. We can forget
         about complex types for the time being as they are relatively unproblematic. 
         </p>
      <p>
         With simple types, we should mention in passing that one of the problems is that while
         processing a schema, we don't always immediately know what the variety of a simple
         type is; if it's derived from a base type and we haven't yet analysed the base type,
         then we park it as a "SimpleTypeDefinition" to be turned into an AtomicType, UnionType,
         or ListType later - which means that all references to the type need to be updated.
         </p>
      <p>
         As well as their use in schema processing, schema types are used as type annotations
         on nodes in XDM, and they also appear in XPath expressions as the target of a "cast"
         or "castable" expression.
         </p>
      <p>
         Item types are purely an XDM concept, and they include atomic types, node types, function
         types, map types, array types. Item types when combined with an occurrence indicator
         form a Sequence type. Sequence types are used in XPath in declaring the types of variables,
         parameters, and function results; they are also used in "instance of" and "treat as"
         expressions.
         </p>
      <p>
         Atomic types are both schema types (more specifically, simple types) and item types.
         Not every schema type is an item type (complex types aren't, list types aren't), and
         not every item type is a schema type (node types and function types aren't). The categories
         overlap, so it's not surprising that the Java class hierarchy is complicated.
         </p>
      <p>
         Union types add another complication. A simple union of atomic types (for example
         the union of xs:date and xs:dateTime) is useful as an item type, for example to define
         the type of a function argument or variable. But XSD union types aren't always simple
         unions of atomic types: they can also include list types, and they can define restrictions
         beyond those present in the member types. So XDM defines the concept of a "pure union
         type", which is a simple union of atomic types; pure union types are the only kind
         that can be used as item types. For convenience it's useful to have a term that embraces
         atomic types and pure union types: the XDM specifications call these "generalized
         atomic types", and in Saxon they are referred to as "plain types". Again, these overlapping
         categories make it very hard to get the Java class hierarchy right.
         </p>
      <p>
         Simple types form a lattice; at the top of this lattice is the most general type "xs:anySimpleType",
         and at the bottom is the "void" type "xs:error" (void because it has no instances).
         These "edge case" types are simple types, but they don't fit cleanly into the classification
         of union types, list types, and atomic types.
         </p>
      <p>
         Item types also overlap with XSLT patterns, and with the node tests used in axis steps.
         Constructs such as element(*) and text() are both node tests (suitable for use in
         patterns and axis steps) and item types. Not every item type is a node test (for example,
         array(*) isn't), and not every node test is an item type (for example, *:local isn't).
         Again, we have two intersecting categories. If we draw the Venn diagram of simple
         types, item types, and node tests, we find that simple tests don't overlap with node
         tests, but all other combinations have an intersection.
         </p>
      <p>
         There's another dimension that we try to capture in the Java class hierarchy: we try
         to distinguish built-in types from user-defined types. There are built-in atomic types
         (xs:integer), built-in list types (xs:NMTOKENS), and built-in union types (xs:numeric);
         and there are also used-defined types in each of the three varieties. Capturing two
         dimensions of classification in a class hierarchy typically introduces multiple inheritance
         and complicates the hierarchy.
         </p>
      <p>
         There's also a lot of complexity concerned with the relationship of schema types to
         other kinds of schema component. Again at this level we try to distinguish used-defined
         schema components (those derived from declarations in an XSD source document) from
         built-in schema components (which include not only simple types, but also complex
         types such as xs:anyType and xs:untyped). We distinguish "schema components" as defined
         in the XSD specification (which include not only schema types, but also element declarations,
         attribute declarations, identity constraints etc) and "schema structures" which are
         essentially constructs in a source XSD document; but looking at the code, nearly everything
         you find in a schema seems to be both a "schema component" and a "schema structure"
         and I'm having trouble seeing exactly what the difference between the two categories
         is.
         </p>
      <p>
         The straw that broke the camel's back and made me examine whether refactoring is needed
         was the introduction of locally-declared union types with the syntax "union(xs:date,
         xs:time)". These are clearly union types, but they aren't built-in, and they don't
         correspond to declarations in any source schema, so they don't fit neatly into the
         existing classification of built-in versus user-defined.
         </p>
      <p>
         We've got an awful lot of multiple inheritance in this hierarchy, and the accepted
         wisdom is that if you've got a lot of multiple inheritance, then you need to do some
         refactoring, and replace some of it with delegation.
         </p>
      <p>
         We've got a model for that in the way we handle XSLT match patterns. Although node-tests
         are a subset of patterns, we don't treat node-tests as a subclass of patterns in the
         Java class hierarchy; rather, the class hierarchy for patterns includes a NodeTestPattern
         which contains a reference to a NodeTest. Similarly, atomic types are a subset of
         schema types, but that doesn't mean they need to implement SchemaType in the Java
         class hierarchy; rather the class hierarchy for SchemaTypes could include an AtomicSchemaType
         which contains a reference to an AtomicType.
         </p>
      <p>
         Let's see what we can do.
         </p>
      <p>
         <b>UPDATE 2020-02-18</b></p>
      <p>Well: I had a good go at refactoring this; but the new scheme was getting just as
         complex as the old, so I decided to revert all the work.
         </p>
      <p>
         I tried to split the classes representing simple types into two: the "compile time"
         information used during XSD schema compilation, and the "executable" types used actively
         for validation. But I ended up with just as many classes (or more), and just as much
         multiple inheritance. I did manage to eliminate the messy process whereby a SimpleTypeDefinition
         is converted to an AtomicType, ListType, or UnionType as soon as we know its variety
         (i.e. when the reference to its base type is resolved -- it can be a forwards reference),
         but I found that doesn't open the door to any wider simplification.
         
         
         
         </p>
   </div></content></entry><entry><title>Java Generics revisited</title><link href="https://blog.saxonica.com/mike/2020/01/java-generics-revisited.html" rel="alternate" type="text/html"/><id>https://blog.saxonica.com/mike/2020/01/java-generics-revisited.html</id><published>2020-01-21T21:14:20Z</published><content type="xhtml" xml:base="https://blog.saxonica.com/mike/2020/01/java-generics-revisited.html"><div xmlns="http://www.w3.org/1999/xhtml">
      
      <p>In Saxon 9.9 we took considerable pains to adopt Java Generics for processing sequences:
         in particular the Sequence and SequenceIterator classes, and all their subclasses,
         became Sequence&lt;? extends Item&gt; and SequenceIterator&lt;? extends Item&gt;.
         </p>
      <p>
         I'm now coming to the conclusion that this was a mistake; or at any rate, that we
         went too far.
         </p>
      <p>
         What exactly are the benefits of using Generics? It's supposed to improve type safety
         and reduce the need for casts which, if applied incorrectly, can trigger run-time
         exceptions. So it's all about detecting more of your errors at compile time.
         </p>
      <p>
         Well, I don't think we've been seeing those benefits. And the main reason for that
         is that in most cases, when we're processing sequences, we don't have any static knowledge
         of the kind of items we are dealing with.
         </p>
      <p>
         Sure, when we process a particular XPath path expression, we know whether it's going
         to deliver nodes or atomic values. But when we write the Java code in Saxon to handle
         path expressions, all we know is that the result will always be a sequence of items.
         </p>
      <p>
         There are some cases where particular kinds of expression only handle nodes, or only
         handle atomic values. For example, the input sequences for a union operator will always
         be sequences of nodes. It would be nice if we didn't have to handle a completely general
         sequence and cast every item to class NodeInfo. But it's an illusion to think we can
         get extra type safety that way. The operands of a union are arbitrary expressions,
         and the iterators returned by the subexpressions are going to be arbitrary iterators;
         there's no way we can translate the type-safety we are implementing at the XPath level
         into type-safe evaluators at the Java level.
         </p>
      <p>
         It's particularly obvious that generics give us no type-safety at the API level. In
         s9api, <b>XPathSelector.evaluate()</b> returns an <b>XdmValue</b>. That's a lot better than the JAXP equivalent which just returns <b>Object</b>, but the programmer still has to do casting to convert the items in the return <b>XdmValue</b> to nodes, string, integers, or whatever. And there's no way we can change that; the
         XPath expression is supplied as a string at run-time, so it's only at run-time that
         we know what type of items it returns. If that's true at the API level, it's equally
         true internally. Any kind of expression can invoke any other kind of expression (that's
         what orthogonality in language design is about), which means that the interfaces between
         an expression and its subexpressions are always going to be general-purpose sequences
         whose item type is known only at execution time.
         </p>
      <p>
         There are a couple of aspects of Java  generics that cause us real pain.
         </p>
      <p>
         
         
         
         <ul>
            <li>The first is the XDM rule that every item is itself a <b>Sequence</b>. So if <b>Sequence</b> is a generic type, parameterized by Item type, and <b>Item</b> is a subclass of <b>Sequence</b>, then <b>Item</b> has to be itself a generic type parameterized by its own type. Rather than <b>Item</b>, it has to be <b>Item&lt;? extends Item&gt;</b>; or perhaps it should be <b>Item&lt;? extends Item&lt;? extends Item&gt;&gt;</b>, and so ad infinitum. And then <b>StringValue</b> extends <b>Item&lt;StringValue&gt; </b>and so on. We found ways around that conundrum, but the complexity is horrendous;
               it certainly doesn't achieve the goal of making it easier to write correct code.</li>
            <li>The second is arrays. Arrays don't play at all well with generics; you can't create
               an array of a generic type, for example. And yet there are lots of places where it's
               useful to use arrays, and some where arrays are the only option. VarArgs functions,
               for example, present their arguments as an array. In some cases we wanted to carry
               on using arrays (rather than lists) for compatibility, in other cases we want to use
               them for convenience or for performance. The natural signature for a function call,
               for example is <b>public Sequence call(Context context, Sequence[] args)</b>. There's no way we can refine this in a way that passes static information about
               the argument types from the caller to the callee, because we're using the same Java
               signature for all XPath functions.</li>
         </ul>
         But having got Generics working, at great effort, in 9.9, should we retain them or
         drop them?
         
         </p>
      <p>
         One reason I'm motivated to drop them is .NET. We have a significant user base on
         .NET, but we have something of a potential crisis looming in terms of ongoing support
         for this platform. Microsoft appear to be basing their future strategy around .NET
         Core, allowing .NET Framework to fade away into the sunset. But the technology we
         use for bridging to .NET, namely IKVM, only supports .NET Framework and not .NET Core;
         and Jeroen Frijters who single-handedly developed IKVM and supported it for umpteen
         years (with no revenue stream to support it) has thrown in the towel and is no longer
         taking it forward. So we're looking at a number of options for a way forward on .NET.
         One of these is source code conversion; and to make source code conversion viable
         without forking the code, we need to minimise our dependencies on Java features that
         don't translate easily to C#. Notable among those features is generics.
         </p>
      <p>
         In the short term, I think I'm going to roll back the use of generics in selected
         areas where they are clearly more trouble than they are worth. That's particularly
         true of <b>Sequence</b> and its subclasses, including <b>Item</b>. For <b>SequenceIterator</b> it's probably worth keeping generics for the time being, but we'll keep that under
         review.
         </p>
   </div></content></entry><entry><title>Alphacodes for Sequence Types</title><link href="https://blog.saxonica.com/mike/2019/10/alphacodes-for-sequence-types.html" rel="alternate" type="text/html"/><id>https://blog.saxonica.com/mike/2019/10/alphacodes-for-sequence-types.html</id><published>2019-10-15T14:06:31Z</published><content type="xhtml" xml:base="https://blog.saxonica.com/mike/2019/10/alphacodes-for-sequence-types.html"><div xmlns="http://www.w3.org/1999/xhtml">
      
      <p>In the next releases of Saxon and Saxon-JS we have devised a compact notation for
         representation of <code><b>SequenceType</b></code> syntax in the exported SEF file. This note is to document this syntax.</p>
      <p>The main aims in devising the syntax were compactness, together with fast generation
         and fast parsing. In addition it has the benefit that some operations are possible
         on the raw lexical form without doing a full parse.</p>
      <p>The syntax actually handles <b>ItemTypes</b> as well as <b>SequenceTypes</b>; and in addition, it can handle the two examples of <b>NodeTests</b> that are not item types, namely<i> *:local</i> and <i>uri:*</i>. It can therefore be used in the SEF wherever a <b>SequenceType</b>, <b>ItemType</b>, or <b>NodeTest</b> is required.</p>
      <p>The first character of an alphacode is the occurrence indicator. This is one of: *
         (zero or more), + (one or more), ? (zero or one), 0 (exactly zero), 1 (exactly one).
         If the first character is not one of these, then "1" is assumed; but the occurrence
         indicator is generally omitted only when representing an item type as distinct from
         a sequence type.</p>
      <p>The occurrence indicator is immediately followed by the "primary alphacode" for the
         item type. These are chosen so that <i>alphacode(T)</i> is a prefix of <i>alphacode(U)</i> if and only if <i>T</i> is a supertype of <i>U</i>. For example, the primary alphacode for <b>xs:integer</b> is "ADI", and the primary alphacode for <b>xs:decima</b>l is "AD", reflecting the fact that <b>xs:integer</b> is a subtype of <b>xs:decimal</b>. The primary alphacodes are as follows:</p>
      <p>"" (zero-length string): item()</p>
      <p>A: xs:anyAtomicType<br/>
         AB: xs:boolean</p>
      <p>AS: xs:string<br/>
         ASN: xs:normalizedString<br/>
         ASNT: xs:token<br/>
         ASNTL: xs:language<br/>
         ASNTM: xs:NMTOKEN<br/>
         ASNTN: xs:Name<br/>
         ASNTNC: xs:NCName<br/>
         ASNTNCI: xs:ID<br/>
         ASNTNCE: xs:ENTITY<br/>
         ASNTNCR: xs:IDREF</p>
      <p>AQ: xs:QName<br/>
         AU: xs:anyURI<br/>
         AA: xs:date<br/>
         AM: xs:dateTime<br/>
         AMP: xs:dateTimeStamp<br/>
         AT: xs:time<br/>
         AR: xs:duration<br/>
         ARD: xs:dayTimeDuration<br/>
         ARY: xs:yearMonthDuration<br/>
         AG: xs:gYear<br/>
         AH: xs:gYearMonth<br/>
         AI: xs:gMonth<br/>
         AJ: xs:gMonthDay<br/>
         AK: xs:gDay</p>
      <p>AD: xs:decimal<br/>
         ADI: xs:integer<br/>
         ADIN: xs:nonPositiveInteger<br/>
         ADINN: xs:negativeInteger<br/>
         ADIP: xs:nonNegativeInteger<br/>
         ADIPP: xs:positiveInteger<br/>
         ADIPL: xs:unsignedLong<br/>
         ADIPLI: xs:unsignedInt<br/>
         ADIPLIS: xs:unsignedShort<br/>
         ADIPLISB: xs:unsignedByte<br/>
         ADIL: xs:long<br/>
         ADILI: xs:int<br/>
         ADILIS: xs:short<br/>
         ADILISB: xs:byte</p>
      <p>AO: xs:double<br/>
         AF: xs:float<br/>
         A2: xs:base64Binary<br/>
         AX: xs:hexBinary<br/>
         AZ: xs:untypedAtomic</p>
      <p>N: node()<br/>
         NE: element(*)<br/>
         NA: attribute(*)<br/>
         NT: text()<br/>
         NC: comment()<br/>
         NP: processing-instruction()<br/>
         ND: document-node()<br/>
         NN: namespace-node()</p>
      <p>F: function(*)<br/>
         FM: map(*)<br/>
         FA: array(*)</p>
      <p>E: xs:error</p>
      <p>X: external (wrapped) object<br/>
         XJ: external Java object<br/>
         XN: external .NET object<br/>
         XS: external Javascript object</p>
      <p>Every item belongs to one or more of these types, and there is always a "most specific"
         type, which is the one that we choose.</p>
      <p>Following the occurrence indicator and primary alphacode are zero or more supplementary
         codes. Each is preceded by a single space, is identified by a single letter, and is
         followed by a parameter value. For example the sequence type "element(BOOK)" is coded
         as "1NE nQ{}BOOK" - here 1 is the occurrence indicator, NE indicates an element node,
         and nQ{}BOOK is the required element name. The identifying letter here is "n". The
         supplementary codes (which may appear in any order) are as follows:</p>
      <p>n - Name, as a URI-qualified name. Used for node names when the primary alphacode
         is one of (NE, NA, NP). Also used for the XSD type name when the type is a user-defined
         atomic or union type: the basic alphacode then represents the lowest common supertype
         that is a built-in type.  (Note: we assume that type names are globally unique. This
         cannot be guaranteed when deploying a SEF file: the schema at the receiving end might
         vary from that of the sender.) Also used for the class name in the case of external
         object types (in this case the namespace part will always be "Q{}"). Note that strictly
         speaking, the forms <i>*:name</i> and <i>name:*</i> can appear in a <b>NameTest</b>, but never in a <b>SequenceType</b>. However, they can be represented in alphacodes using the syntax <b>"n*:name"</b> and <b>"nQ{uri}*"</b> respectively. The syntax <b>"~localname"</b> is used for a name in the XSD namespace. </p>
      <p>c - Node content type (XSD type annotation), as a URI-qualified name optionally followed
         by "?" to indicate nillable. The syntax "~localname" is used for a name in the XSD
         namespace. Optionally present when the basic code is (NE, NA); omitted for NE when
         the content is <b>xs:untyped</b>, and for NA when the content is <b>xs:untypedAtomic</b>. Only relevant for schema-aware code.</p>
      <p>k - Key type, present when the basic code is FM (i.e. for maps), omitted if the key
         type is <b>xs:anyAtomicType</b>. The value is the alphacode of the key type, enclosed in square brackets: it will
         always start with "1A".</p>
      <p>v - Value type, present when when the basic code is (FM, FA) (i.e. for maps and arrays),
         omitted if the value type is <b>item()*</b>. The value is the alphacode of the value type, enclosed in square brackets. For example
         the alphacode for <b>array(xs:string+)* </b>is "*FA v[+AS]".</p>
      <p>r - Return type, always present for functions. The value is the alphacode of the return
         type, enclosed in square brackets.</p>
      <p>a - Argument types, always present for functions. The value is an array of alphacodes,
         enclosed in square brackets and separated by commas. For example, the alphacode for
         the function <b>fn:dateTime#2</b> (with signature <i>($arg1 as xs:date?, $arg2 as xs:time?) as xs:dateTime?)</i> is "1F r[?AM] a[?AA,?AT]"</p>
      <p>m - Member types of an anonymous union type. The value is an array of alphacodes for
         the member types (these will always be atomic types), enclosed in square brackets
         and comma-separated. The basic code in this case will be "A", indicating xs:anyAtomicType.
         This is not used for the built-in union type xs:numeric, nor for user-defined atomic
         types defined in a schema; it is used only for anonymous union types defined using
         the Saxon extension syntax "union(a, b, c)".</p>
      <p>e - Element type of a document-node() type, present optionally when the basic code
         is ND. The value is an alphacode, which will always start with "1NE".</p>
      <p>t - Components of a tuple type (Saxon extension). The value is an array of tokens,
         enclosed in square brackets, where each token comprises the name of the component
         (an NCName), a colon, and the alphacode of the component type.</p>
      <p>i, u, d - Venn type. The item type is the intersection, union, or difference of two
         item types. The letter "i", "u", or "d" indicates intersection, union, or difference
         respectively, followed by a list of (currently always two) item types enclosed in
         square brackets and separated by a comma. The principal type will typically be "N"
         or "NE". Saxon uses venn types internally to give a more precise inferred type for
         expressions; it is probably largely unused at run-time, and can therefore be safely
         ignored when reading a SEF file.</p>
      <p>Named union types have a basic alphacode of "A", followed by the name of the union
         type in the form "A nQ{uri}local". The syntax "~localname" is used for a name in the
         XSD namespace, so the built-in union types xs:numeric and xs:error are represented
         as "A n~numeric" and "A n~error" respectively.</p>
      <p><i>TODO: the documentation for union types is not aligned with the current implementation</i></p>
      <p>Examples:</p>
      <p>0 - empty-sequence()</p>
      <p>1AS - xs:string</p>
      <p>1N - node()</p>
      <p>1 - item()</p>
      <p>* - item()*</p>
      <p>1NE nQ{}item - element(item)</p>
      <p>1ND e[1NE nQ{}item] - document-node(element(item))</p>
      <p>*FM k[1AS] v[?AS] - map(xs:string, xs:string?)*</p>
      <p>1F a[?AS,*AO] r[1AB] - function(xs:string?, xs:double*) as xs:boolean</p>
      <p>Version: 2019-10-30</p>
   </div></content></entry><entry><title>A new push event API</title><link href="https://blog.saxonica.com/mike/2019/05/a-new-push-event-api.html" rel="alternate" type="text/html"/><id>https://blog.saxonica.com/mike/2019/05/a-new-push-event-api.html</id><published>2019-05-01T16:34:00Z</published><content type="xhtml" xml:base="https://blog.saxonica.com/mike/2019/05/a-new-push-event-api.html"><div xmlns="http://www.w3.org/1999/xhtml">
      
      <p>For various internal and performance reasons, we're making some changes to Saxon's
         internal Receiver interface for the next release. This interface is a SAX-like interface
         for sending an XML document (or in general, any XDM instance) from one processing
         component to another, as a sequence of events such as startElement(), attributes(),
         characters(), and so on.
         </p>
      <p>
         The interface is very widely used within Saxon: it handles communication from the
         XML parser to the document builder, document validation, serialization, and much else.
         It also allows instructions to be executed in "push mode", so for example when XSLT
         constructs a result tree, the tree is never actually constructed in memory, but instead
         events representing the tree are sent straight from the transformer to the serializer.<br/>
         I know that although this interface is labelled as internal, some user applications
         attempt either to implement the interface or to act as a client, sending events to
         one of Saxon's many implementations of the interface. So in making changes, it seems
         a good time to recognize that there is a need for an interface at this level, and
         that existing candidates are really rather clumsy to use.
         
         </p>
      <p>
         Among those candidates are the venerable SAX ContentHandler interface, and the newer
         StAX XMLStreamWriter interface.
         </p>
      <p>
         There are a number of structural reasons that make the ContentHandler hard to use:
         </p>
      <p>
         
         
         
         <ul>
            <li>It offers a number of different configuration options for XML parsers, which cause
               namespace information to be provided in different ways. But the ContentHandler has
               no way of discovering which of these options the XML parser (or other originator of
               events) is actually using.</li>
            <li>It's not actually one interface but several: some events are sent not to the ContentHandler,
               but to a LexicalHandler or DTDHandler.</li>
            <li>The information available to the ContentHandler doesn't align well with the information
               defined in the XDM data model; for example, comments are available only to the LexicalHandler,
               not to the ContentHandler</li>
         </ul>
         In addition, the way QNames and namespaces are handled makes life unnecessarily difficult
         for both sides of the interface.
         
         </p>
      <p>
         In some ways the XMLStreamWriter is an improvement, and I've certainly used it in
         preference when writing an application that has to construct XML documents in this
         way. But a major problem of the XMLStreamWriter is that it's underspecified, to the
         extent that there is a separate guidance document from a third-party suggesting how
         implementations should interpret the spec. Again, the main culprit is namespace.
         </p>
      <p>
         One of the practical problems with all these event-based interfaces is that debugging
         can be very difficult. In particular, if you forget to issue an endElement() call,
         you don't find out until the endDocument() event finds there's a missing end tag somewhere,
         and tracking down where the unmatched startElement() is in a complex program can be
         a nightmare. I decided that addressing this problem should be one of the main design
         aims of a new interface -- and it turns out that it isn't difficult.
         </p>
      <p>
         Let's show off the new design with an example. Here is some code from Saxon's InvalidityReportGenerator,
         which generates an XML report of errors found during a schema validation episode,
         using the XMLStreamWriter interface:
         </p>
      <pre><strong>writer</strong>.writeStartElement(<strong>REPORT_NS</strong>, <strong>"meta-data"</strong>);
<strong>writer</strong>.writeStartElement(<strong>REPORT_NS</strong>,<strong>"validator"</strong>);
<strong>writer</strong>.writeAttribute(<strong>"name"</strong>, Version.<em>getProductName</em>() + <strong>"-" </strong>+ getConfiguration().getEditionCode());
<strong>writer</strong>.writeAttribute(<strong>"version"</strong>, Version.<em>getProductVersion</em>());
<strong>writer</strong>.writeEndElement(); //&lt;/validator&gt;
<strong>writer</strong>.writeStartElement(<strong>REPORT_NS</strong>,<strong>"results"</strong>);
<strong>writer</strong>.writeAttribute(<strong>"errors"</strong>, <strong>"" </strong>+ <strong>errorCount</strong>);
<strong>writer</strong>.writeAttribute(<strong>"warnings"</strong>, <strong>"" </strong>+ <strong>warningCount</strong>);
<strong>writer</strong>.writeEndElement(); //&lt;/results&gt;
<strong>writer</strong>.writeStartElement(<strong>REPORT_NS</strong>,<strong>"schema"</strong>);
<strong>if </strong>(<strong>schemaName </strong>!= <strong>null</strong>) {
    <strong>writer</strong>.writeAttribute(<strong>"file"</strong>, <strong>schemaName</strong>);
}
<strong>writer</strong>.writeAttribute(<strong>"xsd-version"</strong>, <strong>xsdversion</strong>);
<strong>writer</strong>.writeEndElement(); //&lt;/schema&gt;
<strong>writer</strong>.writeStartElement(<strong>REPORT_NS</strong>,<strong>"run"</strong>);
<strong>writer</strong>.writeAttribute(<strong>"at"</strong>, DateTimeValue.<em>getCurrentDateTime</em>(<strong>null</strong>).getStringValue());
<strong>writer</strong>.writeEndElement(); //&lt;/run&gt;
<strong>writer</strong>.writeEndElement(); //&lt;/meta-data&gt;</pre>
      <p>And here is the equivalent using the new push API:</p>
      <pre>Push.Element metadata = <strong>report</strong>.element(<strong>"meta-data"</strong>);
metadata.element(<strong>"validator"</strong>)
        .attribute(<strong>"name"</strong>, Version.<em>getProductName</em>() + <strong>"-" </strong>+ getConfiguration().getEditionCode())
        .attribute(<strong>"version"</strong>, Version.<em>getProductVersion</em>());
metadata.element(<strong>"results"</strong>)
        .attribute(<strong>"errors"</strong>, <strong>"" </strong>+ <strong>errorCount</strong>)
        .attribute(<strong>"warnings"</strong>, <strong>"" </strong>+ <strong>warningCount</strong>);
metadata.element(<strong>"schema"</strong>)
        .attribute(<strong>"file"</strong>, <strong>schemaName</strong>)
        .attribute(<strong>"xsd-version"</strong>, <strong>xsdversion</strong>);
metadata.element(<strong>"run"</strong>)
        .attribute(<strong>"at"</strong>, DateTimeValue.<em>getCurrentDateTime</em>(<strong>null</strong>).getStringValue());
metadata.close();</pre>
      <p>What's different?
         The most obvious difference is that the method for creating a new element returns
         an object (a Push.Element) which is used for constructing the attributes and children
         of the element. This gives it an appearance rather like a tree-building API, but this
         is an illusion: the objects created are transient. Methods such as attribute() use
         the "chaining" design - they return the object to which they are applied - making
         it easy to apply further methods to the same object, without the need to bind variables.
         The endElement() calls have disappeared - an element is closed automatically when
         the next child is written to the parent element, which we can do because we know which
         element the child is being attached to.</p>
      <p>There are a few other features of the design worthy of attention:</p>
      <ul>
         <li>Names of elements and attributes can be supplied either as a plain local name, or
            as a QName object. A plain local name is interpreted as being in the default namespace
            in the case of elements (the default namespace can be set at any level), or as being
            in no namespace in the case of attributes. For the vast majority of documents, there
            is never any need to use QNames; very often the only namespace handling is a single
            call on setDefaultNamespace().</li>
         <li>The close() method on elements (which generates the end tag) is optional. If you write
            another child element, the previous child is closed automatically. If you close a
            parent element, any unclosed child element is closed automatically. The specimen code
            above shows one call on close(), which is useful in this case for readability: the
            reader can see that no further children are going to be added.</li>
         <li>The argument of methods such as attribute() and text() that supplies the content may
            always be null. If the content is null, no attribute or text node is written. This
            makes it easier to handle optional content without disrupting the method chaining.</li>
      </ul>
      <p>I have rewritten several classes that construct content using push APIs to use this
         interface, and the resulting readability is very encouraging.</p>
   </div></content></entry><entry><title>Representing namespaces in XDM tree models</title><link href="https://blog.saxonica.com/mike/2019/02/representing-namespaces-in-xdm-tree-models.html" rel="alternate" type="text/html"/><id>https://blog.saxonica.com/mike/2019/02/representing-namespaces-in-xdm-tree-models.html</id><published>2019-02-01T11:59:58Z</published><content type="xhtml" xml:base="https://blog.saxonica.com/mike/2019/02/representing-namespaces-in-xdm-tree-models.html"><div xmlns="http://www.w3.org/1999/xhtml">
      
      <p>Most tree representations of XML, including the Saxon TinyTree and LinkedTree implementation,
         as well as DOM, represent namespace information by holding a set of namespace declarations
         and undeclarations on each element node.
         </p>
      <p>
         I'm considering a change to this representation (for the Saxon implementations) to
         do something that more closely reflects the way namespaces are actually defined in
         XDM: each element node has a set of in-scope namespaces (held in a NamespaceMap object)
         containing all the information about the namespaces that apply to that element.
         </p>
      <p>
         The obvious objection to this, and the reason I've never done it before, is that it
         looks at first sight to be very inefficient. But consider:
         </p>
      <p>
         (a) in the vast majority of documents, there are very few namespace declarations on
         any element other than the root
         </p>
      <p>
         (b) if there are no namespace declarations on an element, it can point to the same
         NamespaceMap object that its parent element points to; in most cases, all elements
         in the document will point to the same shared NamespaceMap.
         </p>
      <p>
         (c) having a NamespaceMap object immediately available on every element node means
         we never need to search up the ancestor axis to resolve namespace prefixes
         </p>
      <p>
         (d) there are still opportunities for implementations of NamespaceMap that use "deltas"
         if space-saving in pathological cases is considered necessary.
         </p>
      <p>
         Note that the NamespaceMap holds prefix=uri pairs, not namespace nodes. Namespace
         nodes have node identity and parentage, which is what makes them so expensive. prefix-uri
         pairs are just pairs of strings without such baggage, and they can be freely shared
         across element nodes.
         </p>
      <p>
         The current implementation I'm using for NamespaceMap is an immutable map implemented
         as a pair of String[] arrays, one for prefixes and one for uris. The prefix array
         is maintained in sorted order so we can use binary search to find a prefix. Insertion
         of a new prefix/uri mapping is O(n), but this doesn't matter because the number of
         bindings is usually less than ten, and it's a rare operation anyway that only happens
         during tree construction.
         </p>
      <p>
         Because the NamespaceMap is immutable, the system is quite easy to implement in a
         tree builder that gets notified of namespaces incrementally (for example by a SAX
         parser). The tree builder maintains a stack of NamespaceMap objects. On a startElement
         event it allocates to the element the same NamespaceMap object that the parent element
         is using; when a namespace declaration or undeclaration is encountered, this is replaced
         with a new NamespaceMap with the required modifications.
         </p>
      <p>
         The real motivation for the change is in implementing copy operations. In complex
         multi-phase transformations both deep and shallow element copy operations are very
         frequent, and copying of the namespace information is a significant cost. The XSLT
         and XQuery language semantics require that when an element is copied, all its in-scope
         namespaces are copied, and this requires searching the ancestor axis to find them
         (we try quite hard to optimize this away, but we're not always successful). If the
         in-scope namespaces are readily to hand in a simple immutable object, we save this
         effort and just pass the complete object down the pipeline.
         </p>
      <p>
         The builder for the tree to which the element is being copied now has to merge this
         set of namespaces with the existing namespaces inherited from ancestor elements on
         the receiving tree. It should now be clear why I chose the particular data structure
         for the NamespaceMap: merging two sets of namespace bindings reduces to merging two
         sorted arrays, which is quite an efficient operation. It's also easy to optimize for
         the common case where the in-scope namespaces of the element being copied are exactly
         the same as the in-scope namespaces of its parent element (typically we'll find that
         the same NamespaceMap object is in use), in which case the merge becomes a null operation.
         </p>
      <p>
         Of course, there are many details to work through (not least, how we fit this in with
         third-party tree models that continue to use declarations and undeclarations). But
         initial experiments are looking encouraging.
         </p>
   </div></content></entry><entry><title>The Receiver Pipeline</title><link href="https://blog.saxonica.com/mike/2018/06/the-receiver-pipeline.html" rel="alternate" type="text/html"/><id>https://blog.saxonica.com/mike/2018/06/the-receiver-pipeline.html</id><published>2018-06-20T11:07:12Z</published><content type="xhtml" xml:base="https://blog.saxonica.com/mike/2018/06/the-receiver-pipeline.html"><div xmlns="http://www.w3.org/1999/xhtml">
      
      <p>A significant feature of the internal architecture of Saxon is the <b style="font-size: 1em;">Receiver</b> pipeline. A receiver is an object that (rather like a SAX ContentHandler) is called
         with a sequence of events such as <i style="font-size: 1em;">startElement()</i>, <i style="font-size: 1em;">characters()</i>, and<i style="font-size: 1em;"> endElement()</i>; it typically does some processing on these events and then calls similar events
         on the next Receiver in the pipeline. The mechanism is efficient, because it avoids
         building a tree in memory, and because it allows much of the conditional logic of
         the processing (for example, whether or not to validate the document) to be executed
         at the time the pipeline is constructed, rather than with conditional code executed
         for every event that occurs.</p>
      <p>Receiver pipelines are used throughout Saxon: from doing whitespace stripping on the
         source document, to serialization of the result tree. The schema validator is implemented
         as a receiver pipeline, as are operations such as namespace fixup.</p>
      <p>But despite the elegance of the design, there have been some perennial problems with
         the implementation. For example, there are variations on exactly what input different
         implementations of Receiver will accept: some for example require an <i>open()</i> event while others don't; some accept entire element or document nodes in an <i>append()</i> event while others don't. This limits the ability to construct a pipeline using arbitrary
         combinations of Receivers, and worse, it's very hard to establish exactly what the
         permitted combinations are.</p>
      <p>This has come to a head recently in trying to get some of the new features in XSLT
         3.0 and XQuery 3.1 working reliably and robustly. The straw that broke the camel's
         back was the innocent-seeming <b>item-separator</b> serialization property. The item-separator is used while doing "sequence normalization"
         as the first stage of serialization; and the problem was that we didn't really do
         sequence normalization as a separate step in the processing. The obvious symptom that
         there are design problems here has been that whenever we get all the XQuery tests
         working, we find we've broken XSLT; and then when we get all the XSLT tests working,
         we find XQuery is now failing.</p>
      <p>The model according to the specs is that the transformation or query engine produces
         "raw" results (which can be any sequence of items), and this is then input to the
         serialization process (or possibly just to sequence normalization, which wraps the
         results in a document node and then delivers the document). But although Saxon could
         deliver raw results from an XQuery running in "pull" mode (the <i>XQueryEvaluator.iterate()</i> method) we never really had the capability to produce raw output in push mode: the
         push code did sequence normalization within the query/transformation logic, rather
         than leaving it to the serializer. That's for historic reasons, of course: with XSLT
         2.0, that's the way it was defined (the result of the transformation was always a
         document, with optional serialization).</p>
      <p>So the first principle to establish in sorting this out is: the interface between
         the query or transformation engine and the Destination (which may or may not be a
         Serializer) is a raw sequence, delivered over the Receiver interface.</p>
      <p>This requires a definition of exactly how a raw sequence is delivered over this interface:
         that is, what's the contract between the provider of the Receiver interface and the
         client (the sender of events). I've created that definition, and I've also written
         a Receiver implementation which validates that the sequence of events conforms to
         this definition; we can put this validation step into the pipeline when we feel it
         useful (for example, when running with assertions enabled). This exercise has revealed
         quite a few anomalies that should be fixed, for example cases where<i> endDocument()</i> is not being called before calling <i>close()</i>.</p>
      <p>There are three ways of delivering output from a query or transformation: raw output,
         document output (the result of sequence normalization), and serialized output. The
         next question that arises is, who decides which form is delivered. The simplest solution
         is: this is decided entirely at the API level, and does not depend on anything in
         the stylesheet or query. (This means that the XSLT build-tree attribute is ignored
         entirely.) In s9api terms, your choice of Destination object determines which kind
         of output you get. And at the implementation level, the Destination object always
         receives raw output; we don't want the transformation engine doing different things
         depending what kind of Destination has been supplied.</p>
      <p>The other related area that needed sorting out was the API interaction with<b> xsl:result-documen</b>t. We've always had the <i>OutputURIResolver</i> as a callback for determining what should happen to secondary result documents, but
         this is no longer fit for purpose. It was already a struggle to extend it to handle
         thread safety when the xsl:result-document instruction became asynchronous; further
         extending it to work with the s9api <i>Destination</i> framework has never been attempted because it just seemed too difficult. Having made
         the decision to introduce a dependency on Java 8 for the next major Saxon release,
         I think we can solve this at the API level with two enhancements:</p>
      <p>
         
         
         <ol>
            <li style="caret-color: black; color: black; font-family: -webkit-standard;">on <i>XsltTransformer</i> and <i>Xslt30Transformer</i>, a new method <i>setResultDocumentResolver()</i> which takes as argument an implementation of <i>Function&lt;URI, Destination&gt;</i> - that is a function that accepts an absolute URI as input, and returns a <i>Destination</i>;</li>
            <li>on <i>Destination</i>, a new method <i>onClose()</i> which takes as argument a <i>Consumer&lt;Destination&gt;</i>.</li>
         </ol>
         </p>
      <p>So when <b>xsl:result-document</b> is called, we construct the absolute URI and pass it to the registered result document
         resolver, and then use the returned <i>Destination</i> to write the result tree. On completion we call any <i>onClose()</i> handler registered with the <i>Destination</i>, which gives the application the opportunity to process the result document (for
         example, by writing it to a database).</p>
      <p>Of course, we have to work out how to implement this while retaining a level of backwards
         compatibility for applications using the existing <i>OutputURIResolver</i>.</p>
      <p>A tricky case with xsl:result-document has been where the href attribute is omitted
         or empty. I think the cleanest design here is to call the registered result document
         resolver passing the base output URI as argument, and use the returned Destination
         in the normal way. The application then has to sort out the fact that the original
         primary Destination for the transformation is not actually used.</p>
      <p>Yet another complication in the design is the rule in XSLT that when <b>xsl:result-document</b> requests schema validation of the output, schema validation is done after sequence
         normalization and before serialization. This is pretty ugly from a specification point
         of view: the serialization spec defines serialization as a 6-step process of which
         sequence normalization is the first; the XSLT spec really has no business inserting
         an additional step in the middle of this process. When the specification is ugly,
         the implementation usually ends up being ugly too, and we have to find some way for
         the transformation engine to inject a validation step into the middle of the pipeline
         implemented by the Destination, which ought by rights to be completely encapsulated.</p>
      <p>Standing back from all this, unlike some refactoring exercises, in this case the basic
         design of the code proved to be sound, but it needed reinforcement to make the implementation
         more robust. It needed a clear definition and enforcement of the contract implied
         by the Receiver interface; it needed a clear separation of concerns between the transformation/query
         engine and the Destination processing; and it needed a clean API to control it all.</p>
   </div></content></entry><entry><title>Navigating XML trees using Java Streams</title><link href="https://blog.saxonica.com/mike/2018/04/navigating-xml-trees-using-java-streams.html" rel="alternate" type="text/html"/><id>https://blog.saxonica.com/mike/2018/04/navigating-xml-trees-using-java-streams.html</id><published>2018-04-13T08:31:44Z</published><content type="xhtml" xml:base="https://blog.saxonica.com/mike/2018/04/navigating-xml-trees-using-java-streams.html"><div xmlns="http://www.w3.org/1999/xhtml">
      
      <p>
         
         
         
         <h2><b>Navigating XML trees using Java Streams</b></h2>
         
         
         </p>
      <p>For the next major Saxon release I am planning an extension to the s9api interface
         to exploit the facilities of Java 8 streams to allow powerful navigation of XDM trees:
         the idea is that navigation should be as easy as using XPath, but without the need
         to drop out of Java into a different programming language. To give a flavour, here
         is how you might select the elements within a document that have @class='hidden':</p>
      <p><code>doc.select(descendant(isElement())</code><br/><code>   .where(attribute("class").eq("hidden")))</code></p>
      <p>We'll see how that works in due course.</p>
      <h2>Why do we need it?</h2>
      <p>The combination of Java and XML is as powerful and ubiquitous today as it as been
         for nearly twenty years.
         Java has moved on considerably (notably, as far as this article is concerned, with
         the Java 8 Streams API),
         and the world of XML processing has also made great strides (we now have XSLT 3.0,
         XPath 3.1, and XQuery 3.1),
         but for some reason the two have not moved together. The bulk of Java programmers
         manipulating XML, if we can
         judge from the questions they ask on forums such as StackOverflow, are still using
         DOM interfaces, perhaps with
         a bit of XPath 1.0 thrown in.</p>
      <p>DOM shows its age. It was originally designed for HTML, with XML added as an afterthought,
         and XML namespaces
         thrown in as a subsequent bolt-on. Its data model predates the XML Infoset and the
         (XPath-2.0-defined) XDM model.
         It was designed as a cross-language API and so the designers deliberately eschewed
         the usual
         Java conventions and interfaces in areas such as the handling of collections and iterators,
         not to mention exceptions.
         It does everything its own way. As a navigational API it carries a lot of baggage
         because the underlying tree is assumed
         to be mutable. Many programmers only discover far too late that it's not even thread-safe
         (even when you confine yourself
         to retrieval-only operations).</p>
      <p>There are better APIs than DOM available (for example JDOM2 and XOM) but they're all
         ten years old and haven't caught up with the times. There's nothing in the Java world
         that compares with Linq for C# users, or ElementTree in Python.</p>
      <p>The alternative of calling out from Java to execute XPath or XQuery expressions has
         its own disadvantages. Any
         crossing of boundaries from one programming language to another involves data conversions
         and a loss of type safety.
         Embedding a sublanguage in the form of character strings within a host language (as
         with SQL and regular expressions)
         means that the host language compiler can't do any static syntax checking or type
         checking of the expressions in the
         sublanguage. Unless users go to some effort to avoid it, it's easy to find that the
         cost of compiling XPath expressions
         is incurred on each execution, rather than being incurred once and amortized. And
         the API for passing context from the
         host language to the sublanguage can be very messy. It doesn't have to be quite as
         messy as the JAXP interface used for
         invoking XPath from Java, but it still has to involve a fair bit of complexity.</p>
      <p>Of course, there's the alternative of not using Java (or other general-purpose programming
         languages) at all: you
         can write the whole application in XSLT or XQuery. Given the capability that XSLT
         3.0 and XQuery 3.1 have acquired, that's
         a real possibility far more often than most users realise. But it remains true that
         if only 10% of your application is
         concerned with processing XML input, and the rest is doing something more interesting,
         then writing the whole application
         in XQuery would probably be a poor choice.</p>
      <p>Other programming languages have developed better APIs. Javascript has JQuery, C#
         programmers have Linq,
         Scala programmers have something very similar, and PHP users have SimpleXML. These
         APIs
         all have the characteristic that they are much more deeply integrated into the host
         language, and in particular they exploit
         the host language primitives for manipulation of sequences through functional programming
         constructs, with a reasonable
         level of type safety given that the actual structure of the XML document is not statically
         known.</p>
      <p>That leads to the question of data binding interfaces: broadly, APIs that exploit
         static knowledge of the schema of the
         source document. Such APIs have their place, but I'm not going to consider them any
         further in this article. In my experience
         they can work well if the XML schema is very simple and very stable. If the schema
         is complex or changing, data binding
         can be a disaster.</p>
      <p>
         
         
         
         
         <section>
            
            
            
            <h2><b>The Java 8 Streams API</b></h2>
            
            
            
            <p>This is not the place for an extended tutorial on the new Streams API introduced in
               Java 8. If you haven't come across
               it, I suggest you find a good tutorial on the web and read it before you go any further.</p>
            
            
            
            <p>Java Streams are quite unrelated to XSLT 3.0 streaming. Well, almost unrelated: they
               share the same high-level objectives
               of processing large collections of data in a declarative way, making maximum use of
               lazy evaluation to reduce memory use,
               and permitting parallel execution. But that's where the similarity ends. Perhaps the
               biggest difference is that Java 8 streams
               are designed to process linear data structures (sequences), whereas XSLT 3.0 streaming
               is designed to process trees.</p>
            
            
            
            <p>But just to summarise:</p>
            
            
            
            <ul>
               <li>Java 8 introduces a new interface, <code>Stream&lt;X&gt;</code>, representing a linear sequence of items of type <code>X</code></li>
               <li>Like iterators, streams are designed to be used once. Unlike iterators, they are manipulated
                  using functional operations,
                  most notably maps and filters, rather than being processed one item at a time. This
                  makes for less error-prone programming,
                  and allows parallel execution.</li>
            </ul>
            
            
            
            <p>The functional nature of the Java 8 Streams API means it has much in common with the
               processing model of XPath. The basic thrust
               of the API design presented in this article is therefore to reproduce the primitives
               of the XPath processing model, re-expressing
               them in terms of the constructs provided by the Java 8 Streams API.</p>
            
            
            
            <p>If the design appears to borrow concepts from other APIs such as LINQ and Scala and
               SimpleXML, that's not actually because I have a deep familiarity
               with those APIs: in fact, I have never used them in anger, and I haven't attempted
               to copy anything across literally. Rather, any similarity is because
               the functional concepts of XPath processing map so cleanly to this approach.</p>
            </section>
         
         
         
         <section>
            
            
            
            <h2>The Basics of the Saxon s9api API</h2>
            
            
            
            <p>The Saxon product primarily exists to enable XSLT, XQuery, XPath, and XML Schema processing.
               Some years ago I decided that the standard
               APIs (JAXP and XQJ) for invoking such functionality were becoming unfit for purpose.
               They had grown haphazardly over the years, the various APIs
               didn't work well together, and they weren't being updated to exploit the newer versions
               of the W3C specifications. Some appalling design mistakes
               had been unleashed on the world, and the strict backwards compatibility policy of
               the JDK meant these could never be corrected. </p>
            
            
            
            <p>To take one horrid example: the
               <code>NamespaceContext</code> interface is used to pass a set of namespace bindings from a Java application to
               an XPath processor. To implement this
               interface, you need to implement three methods, of which the XPath processor will
               only ever use one (<code>getNamespaceURI(prefix)</code>). Yet
               at the same time, there is no way the XPath processor can extract the full set of
               bindings defined in the <code>NamespaceContext</code> and copy them
               into its own data structures.</p>
            
            
            
            <p>So I decided some years ago to introduce a proprietary alternative called <b>s9api</b> into the Saxon product (retaining JAXP support alongside), and it has been a considerable
               success, in that it has withstood the test of time rather well. The changes to XSLT
               transformation in 3.0 were sufficiently radical that I forked the
               <code>XsltTransformer</code> interface to create a 3.0 version, but apart from that it has been largely possible
               to add new features incrementally. That's partly
               because of a slightly less obsessive attitude to backwards compatibility: if I decide
               that something was a bad mistake, I'm prepared to change it.</p>
            
            
            
            <p>Although s9api is primarily about invoking XSLT, XQuery, and XPath processing, it
               does include classes that represent objects in the XDM data model,
               and I will introduce these briefly because the new navigation API relies on these
               objects as its foundation. The table below lists the main classes.</p>
            
            
            
            <table>
               
               
               
               <thead>
                  
                  
                  
                  <tr>
                     
                     
                     
                     <th>Class</th>
                     
                     
                     
                     <th>Description</th>
                     </tr>
                  </thead>
               
               
               
               <tbody>
                  
                  
                  
                  <tr>
                     
                     
                     
                     <td valign="top"><code>XdmValue</code></td>
                     
                     
                     
                     <td>Every value is the XDM model is a sequence of items. The <code>XdmValue</code> class is therefore
                        the top of the class hierarchy. Because it's a sequence, it implements <code>Iterable&lt;XdmItem&gt;</code>,
                        so you can use a Java <code>foreach</code> loop to process the items sequentially. In the latest version
                        I have used Java generics to add a type parameter, so <code>XdmValue&lt;XdmNode&gt;</code> is a sequence
                        of nodes, and <code>XdmValue&lt;XdmAtomicValue&gt;</code> is a sequence of atomic values. As well as
                        an <code>iterator()</code> method, it has an <code>itemAt()</code> method to get the <i>N</i>th item,
                        and a <code>size()</code> method to count the items.
                        Internally an <code>XdmValue</code> might exist as an actual sequence in memory, or as a "promise": sufficient
                        data to enable the items to be materialized when they are needed.</td>
                     </tr>
                  
                  
                  
                  <tr>
                     
                     
                     
                     <td valign="top"><code>XdmItem</code></td>
                     
                     
                     
                     <td>This class represents an Item in the XDM model. As such it is both a component of
                        an <code>XdmValue</code>,
                        and also an <code>XdmValue</code> (of length one) in its own right. It's an abstract class, because every
                        item is actually something more specific (a node, an atomic value, a function). Some
                        of the methods
                        inherited from <code>XdmValue</code> become trivial (for example <code>size()</code> always returns 1).
                        </td>
                     </tr>
                  
                  
                  
                  <tr>
                     
                     
                     
                     <td valign="top"><code>XdmNode</code></td>
                     
                     
                     
                     <td>This is a subclass of <code>XdmItem</code> used to represent nodes. Unlike many models of XML, we don't
                        subclass this for different kinds of node: that's mainly because XDM has deliberately
                        aimed at uniformity,
                        with the same accessors available for all node kinds. Many of the methods on <code>XdmNode</code>, such
                        as <code>getNodeName()</code>, <code>getStringValue()</code>, <code>getTypedValue()</code>, and
                        <code>getNodeKind()</code>, are directly equivalent to accessors defined in the W3C XDM specification.
                        But in addition, <code>XdmNode</code> has a method <code>axisIterator</code> to navigate the tree
                        using any of the XPath axes, the result being returned as an iterator over the selected
                        nodes.</td>
                     </tr>
                  
                  
                  
                  <tr>
                     
                     
                     
                     <td valign="top"><code>XdmAtomicValue</code></td>
                     
                     
                     
                     <td>Another subclass of <code>XdmItem</code>, this is used to represent atomic values in the XDM model.
                        As with <code>XdmNode</code>, we don't define further subclasses for different atomic types. There are convenience
                        methods to convert <code>XdmAtomicValue</code> instances to and from equivalent (or near-equivalent) Java
                        classes such as <code>String</code>, <code>Double</code>, <code>BigInteger</code>, and <code>Date</code>.</td>
                     </tr>
                  
                  
                  
                  <tr>
                     
                     
                     
                     <td valign="top"><code>XdmFunctionItem</code></td>
                     
                     
                     
                     <td>From XPath 3.0, functions are first-class values alongside nodes and atomic values.
                        These are
                        represented in s9api as instances of <code>XdmFunctionItem</code>. Two specific subclasses of function,
                        with their own behaviours, are represented using the subclasses <code>XdmMap</code> and <code>XdmArray</code>.
                        I won't be saying much about these in this article, because I'm primarily concerned
                        with navigating
                        XML trees.</td>
                     </tr>
                  </tbody>
               </table>
            </section>
         
         
         
         <section>
            
            
            <h2>The new API: Steps and Predicates</h2>
            
            
            
            <p>The basic concept behind the new extensions to the s9api
               API is navigation using steps and predicates. I'll introduce
               these concepts briefly in this section, and then go on to
               give a more detailed exposition.</p>
            
            
            
            <p>The class <code>XdmValue&lt;T&gt;</code> acquires a new method:</p>
            
            
            
            <p><code>XdmStream select(Step step)</code></p>
            
            
            
            <p>The <code>Step</code> here is a function that takes an item of class <code>T</code> as its input, and returns a stream of items. If we consider a very simple <code>Step</code>, namely <code>child()</code>, this takes a node as input and returns a stream of nodes
               as its result. We can apply this step to an <code>XdmValue</code> consisting entirely of nodes, and it returns the concatenation of the streams
               of nodes obtained by applying the step to each node in the input value. This operation
               is equivalent to the "!" operator in XPath 3.0, or to the
               <code>flatMap()</code> method in many functional programming languages. It's not quite the same as the familiar
               "/" operator in XPath, because
               it doesn't eliminate duplicates or sort the result into document order. But for most
               purposes it does the same job.</p>
            
            
            
            
            <p>There's a class <code>net.sf.saxon.s9api.streams.Steps</code> containing static methods which provide commonly-used steps such
               as <code>child()</code>. In my examples, I'll assume
               that the Java application has <code>import net.sf.saxon.s9api.streams.Steps.*;</code> in its header, so it can use these fields and methods without further
               qualification.</p>
            
            
            
            
            <p>One of the steps defined by this class is <code>net.sf.saxon.s9api.streams.Steps.child()</code>: this step is a function which, given a node, returns its children. There are
               other similar steps for the other XPath axes. So you can find the children of a node
               <code>N</code> by writing <code>N.select(child())</code>.</p>
            
            
            
            
            <p>Any two steps <code>S</code> and <code>T</code>
               can be combined into a single composite step by writing <code>S.then(T)</code>: for example <code>Step grandchildren = child().then(child())</code> gives you
               a step which can be used in the expression <code>N.select(grandchildren)</code> to select all the grandchildren.</p>
            
            
            
            
            <p>The class <code>Step</code> inherits from the standard Java class <code>Function</code>, so it can be used more generally in any Java context where a
               <code>Function</code> is required.</p>
            
            
            
            
            <p><code>Predicate&lt;T&gt;</code> is a standard Java 8 class: it defines a function that can be applied to an object
               of type <code>T</code> to return
               true or false. The class <code>net.sf.saxon.s9api.streams.Predicates</code> defines some standard predicates that are useful when processing XML. For example
               <code>isElement()</code> gives you a predicate that can be applied to any <code>XdmItem</code> to determine if it is an element node.</p>
            
            
            
            
            <p>Given a <code>Step</code> <code>A</code> and a <code>Predicate</code> <code>P</code>, the expression <code>A.where(P)</code> returns a new
               <code>Step</code> that filters the results of <code>A</code> to include only those items that satisfy the predicate <code>P</code>. So, for example,
               <code>child().where(isElement())</code> is a step that selects the element children of a node, so that <code>N.select(child().where(isElement()))</code>
               selects the element children of <code>N</code>. This is sufficiently common that we provide a shorthand: it can also be written
               
               <code>N.select(child(isElement()))</code>.</p>
            
            
            
            
            <p>The predicate <code>hasLocalName("foo")</code> matches nodes having a local name of "foo": so <code>N.select(child().where(hasLocalName("foo"))</code>
               selects the relevant children. Again this is so common that we provide a shorthand:
               <code>N.select(child("foo"))</code>. There is also a two argument version
               <code>child(ns, "foo")</code> which selects children with a given namespace URI and local name.</p>
            
            
            
            
            <p>Another useful predicate is <code>exists(step)</code> which tests whether the result of applying a given step returns at least one item.
               So, for example
               <code>N.select(child().where(exists(attribute("id"))))</code> returns those children of <code>N</code> that have an attribute named "id".</p>
            
            
            
            
            <p>The result of the <code>select()</code> method is always a stream of items, so you can use methods from the Java Stream class
               such as filter() and flatMap() to process the result. Here are some of the standard
               things you can do
               with a stream of items in Java:</p>
            
            
            
            
            <ul>
               <li>You can get the results as an array: <code>N.select(child()).toArray()</code></li>
               <li>Or as a list: <code>N.select(child()).collect(Collectors.toList())</code></li>
               <li>You can apply a function to each item in the stream: <code>N.select(child()).forEach(System.err::println)</code></li>
               <li>You can get the first item in the stream: <code>N.select(child()).findFirst().get()</code></li>
            </ul>
            
            
            
            
            <p>However, Saxon methods such as <code>select()</code> always return a subclass of <code>Stream</code> called <code>XdmStream</code>, and this offers additional methods. For example:</p>
            
            
            
            
            <ul>
               <li>You can get the results as an <code>XdmValue</code>: <code>N.select(child()).asXdmValue()</code></li>
               <li>A more convenient way to get the results as a Java <code>List</code>: <code>N.select(child()).asList()</code></li>
               <li>If you know that the stream contains a single node (or nothing), you can get this
                  using the methods <code>asNode()</code>
                  or <code>asOptionalNode()</code></li>
               <li>Similarly, if you know that the stream contains a single atomic value (or nothing),
                  you can get this using the methods <code>asAtomic()</code> or <code>asOptionalAtomic()</code></li>
               <li>You can get the last item in the stream: <code>N.select(child("para")).last()</code></li>
            </ul>
            
            
            
            
            <section>
               
               
               
               <h2><b>More about Steps</b></h2>
               
               
               
               <p>The actual definition of the <code>Step</code> class is:</p>
               
               
               
               
               <p><code>public abstract class Step&lt;T extends XdmItem&gt;
                     implements Function&lt;XdmItem, Stream&lt;? extends T&gt;&gt; </code></p>
               
               
               
               
               <p>What that means is that it's a function that any <code>XdmItem</code> as input, and delivers a stream of <code>U</code> items as its result (where <code>U</code> is <code>XdmItem</code>
                  or some possibly-different subclass). (I experimented by also parameterizing the class
                  on the type of items accepted, but that didn't work out well.)</p>
               
               
               
               
               <p>Because the types are defined, Java can make type inferences: for example it knows
                  that <code>N.select(child())</code> will return nodes
                  (because <code>child()</code> is a step that returns nodes).</p>
               
               
               
               
               <p>As a user of this API, you can define your own kinds of <code>Step</code> if you want to: but most of the time you will be able to do everything
                  you need with the standard Steps available from the class <code>net.sf.saxon.s9api.stream.Steps</code>. The standard steps include:</p>
               
               
               
               
               <ul>
                  <li>The axis steps <code>ancestor()</code>, <code>ancestor-or-self()</code>, <code>attribute()</code>, <code>child()</code>,
                     <code>descendant()</code>, <code>descendantOrSelf()</code>, <code>following()</code>, <code>followingSibling()</code>,
                     <code>namespace()</code>, <code>parent()</code>, <code>preceding()</code>, <code>precedingSibling()</code>,
                     <code>self()</code>.</li>
                  <li>For each axis, three filtered versions: for example <code>child("foo")</code> filters the axis to select elements by
                     local name (ignoring the namespace if any); <code>child(ns, local)</code> filters the axis to select elements by
                     namespace URI and local name, and <code>child(predicate)</code> filters the axis using an arbitrary predicate: this is
                     a shorthand for <code>child().where(predicate)</code>.</li>
                  <li>A composite step can be constructed using the method <code>step1.then(step2)</code>. This applies <code>step2</code>
                     to every item in the result of <code>step1</code>, retaining the order of results and flattening them into a single stream.</li>
                  <li>A filtered step can be constructed using the method <code>step1.where(predicate1)</code>. This selects those items in the
                     result of <code>step1</code> for which <code>predicate1</code> returns true.</li>
                  <li>A path with several steps can be constructed using a call such as<code>path(child(isElement()), attribute("id"))</code>. This returns a step whose effect is to return the <code>id</code> attributes of all the children of the target node.</li>
                  <li>If the steps are sufficiently simple, a path can also by written means of a simple
                     micro-syntax similar to XPath abbreviated steps. The previous example could also be
                     written <code>path("*", "@id")</code>. Again, this returns a step that can be used like any other step.
                     (In my own applications, I have found myself using this approach very extensively).</li>
                  <li>The step <code>atomize()</code> extracts the typed values of nodes in the input, following the rules in the XPath
                     specification. The result
                     is a stream of atomic values</li>
                  <li>The step <code>toString()</code> likewise extracts the string values, while <code>toNumber()</code> has the same effect as the
                     XPath <code>number()</code> function</li>
               </ul>
               
               
               
               
               <p>Last but not least, <code>xpath(path)</code> returns a <code>Step</code> that evaluates an XPath expression. For example,
                  <code>doc.select(xpath("//foo"))</code> has the same effect as <code>doc.select(descendant("foo"))</code>. A second argument
                  to the <code>xpath()</code> method may be used to supply a static context for the evaluation. Note that compilation
                  of the XPath expression
                  occurs while the step is being created, not while it is being evaluated; so if you
                  bind the result of <code>xpath("//foo")</code> to
                  a variable, then the expression can be evaluated repeatedly without recompilation.</p>
               </section>
            
            
            
            <section>
               
               
               
               <h2><b>More about Predicates</b></h2>
               
               
               
               <p>The <code>Predicate</code> class is a standard Java 8 interface: it is a function that takes any object as input,
                  and returns a boolean.
                  You can use any predicates you like with this API, but the class <code>net.sf.saxon.s9api.streams.Predicates</code> provides some implementations
                  of <code>Predicate</code> that are particularly useful when navigating XML documents. These include the following:</p>
               
               
               
               
               <ul>
                  <li><code>isElement()</code>, <code>isAttribute()</code>, <code>isText()</code>, <code>isComment()</code>,
                     <code>isDocument()</code>, <code>isProcessingInstruction()</code>, <code>isNamespace()</code> test that the item
                     is a node of a particular kind</li>
                  <li><code>hasName("ns", "local")</code>, <code>hasLocalName("n")</code>, and <code>hasNamespaceUri("ns")</code> make tests
                     against the name of the node</li>
                  <li><code>hasType(t)</code> tests the type of the item: for example <code>hasType(ItemType.DATE)</code> tests for
                     atomic values of type <code>xs:date</code></li>
                  <li><code>exists(step)</code> tests whether the result of applying the given step is a sequence containing at least
                     one item; conversely <code>empty(step)</code> tests whether the result of the step is empty. For example, <code>exists(CHILD)</code>
                     is true for a node that has children.</li>
                  <li><code>some(step, predicate)</code> tests whether at least one item selected by the step satisfies the given predicate.
                     For example,
                     <code>some(CHILD, IS_ELEMENT)</code> tests whether the item is a node with at least one element child. Similarly <code>every(step, predicate)</code>
                     tests whether the predicate is true for every item selected by the step.</li>
                  <li><code>eq(string)</code> tests whether the string value of the item is equal to the given string; while <code>eq(double)</code> does
                     a numeric comparison. A two-argument version <code>eq(step, string)</code> is shorthand for <code>some(step, eq(string))</code>.
                     For example, <code>descendant(eq(attribute("id"), "ABC"))</code> finds all descendant elements
                     having an "id" attribute equal to "ABC".</li>
                  <li>Java provides standard methods for combining predicates using <code>and</code>, <code>or</code>, and <code>not</code>. For example
                     <code>isElement().and(eq("foo"))</code> is a predicate that tests whether an item is an element with string-value "foo".</li>
               </ul>
               </section>
            
            
            
            <section>
               
               
               
               <h2><b>The XdmStream class</b></h2>
               
               
               <p>The fact that all this machinery is built on Java 8 streams and functions is something
                  that many users can safely ignore; they are essential foundations, but they are hidden
                  below the surface. At the same time, a user who understands that steps and predicates
                  are Java Functions, and that the result of the select() method is a Java Stream, can
                  take advantage of this knowledge.
                  
                  
                  </p>
               
               
               <p>
                  
                  
                  One of the key ideas that made this possible was the idea of subclassing <code>Stream</code> with <code>XdmStream</code>. This idea was shamelessly stolen from the open-source <strong>StreamEx</strong> library by Tagir Valeev (though no StreamEx code is actually used). Subclassing <code>Stream</code> enables additional methods to be provided to handle the results of the stream, avoiding
                  the need for clumsy calls on the generic <code>collect()</code> method. Another motivating factor here is to allow for early exit (short-circuit
                  evaluation) when a result can be delivered without reading the whole stream. Saxon
                  handles this by registering <code>onClose()</code> handlers with the stream pipeline, so that when the consumer of the stream calls
                  the <code>XdmStream.close()</code> method, the underlying supplier of data to the stream is notified that no more data
                  is needed.
                  </p>
               
               
               
               <h2><b>Examples</b></h2>
               
               
               
               <p>This section provides some examples extracted from an actual program that uses s9api
                  interfaces and does a
                  mixture of Java navigation and XPath and XQuery processing
                  to extract data from an input document.</p>
               
               
               
               
               <p>First, some very simple examples. Constructs like this are not uncommon:</p>
               
               
               
               <p><code>XdmNode testInput = (XdmNode) xpath.evaluateSingle("test", testCase);</code></p>
               
               
               
               <p>This can be replaced with the much simpler and more efficient:</p>
               
               
               
               <p><code>XdmNode testInput = testCase.selectFirst(child("test"));</code></p>
               
               
               
               <p>Similarly, the slightly more complex expression:</p>
               
               
               
               <p><code>XdmNode principalPackage = (XdmNode) xpath.evaluateSingle("package[@role='principal']",
                     testInput);</code></p>
               
               
               
               <p>becomes:</p>
               
               
               
               <p><code>XdmNode principalPackage = testInput.selectFirst(child("package").where(eq(attribute("role"),
                     "principal"));</code></p>
               
               
               
               
               <p>A more complex example from the same application is this one:</p>
               
               
               
               <p><code>boolean definesError = xpath.evaluate("result//error[starts-with(@code, 'XTSE')]",
                     testCase).size() &gt; 0;
                     </code></p>
               
               
               
               <p>Note here how the processing is split between XPath code and Java code. This is also
                  using an XPath function for which we haven't provided a built-in
                  predicate in s9api. But that's no problem, because we can invoke Java methods as predicates.
                  So this becomes:</p>
               
               
               
               <pre><code>boolean definesError = testCase.selectFirst(child("result"), descendant("error").where(
                     some(attribute("code"), (XdmNode n) -&gt; n.getStringValue().startsWith("XTSE"))) != null;</code></pre>
               
               
               </section>
            
            </section>
         </p>
   </div></content></entry><entry><title>Capturing Accumulators</title><link href="https://blog.saxonica.com/mike/2018/03/capturing-accumulators.html" rel="alternate" type="text/html"/><id>https://blog.saxonica.com/mike/2018/03/capturing-accumulators.html</id><published>2018-03-28T08:09:03Z</published><content type="xhtml" xml:base="https://blog.saxonica.com/mike/2018/03/capturing-accumulators.html"><div xmlns="http://www.w3.org/1999/xhtml">
      
      <p>A <a href="https://stackoverflow.com/questions/48983320/conditional-streaming-accumulator-in-xslt-3/48985112">recent post on StackOverflow</a> made me realise that streaming accumulators in XSLT 3.0 are much harder to use than
         they need to be.
         </p>
      <p>
         
         
         A reminder about what accumulators do. The idea is that as you stream your way through
         a large document, you can have a number of tasks running in the background (called
         accumulators) which observe the document as it goes past, and accumulate information
         which is then available to the "main" line of processing in the foreground. For example,
         you might have an accumulator that simply keeps a note of the most recent section
         heading in a document; that's useful because the foreground processing can't simply
         navigate around the document to find the current section heading when it finds that
         it's needed.
         </p>
      <p>
         Accumulator rules can fire either on start tags or end tags or both, or they can be
         associated with text nodes or attributes. But there's a severe limitation: a streaming
         accumulator must be motionless: that's XSLT 3.0 streaming jargon to say that it can
         only see what's on the parser's stack at the time the accumulator triggers. This affects
         both the pattern that controls when the accumulator is triggered, and the action that
         it can take when the rule fires.
         </p>
      <p>
         
         
         For example, you can't fire a rule with the pattern <code>match="section[title='introduction']"</code> because navigation to child elements (title) is not allowed in a motionless pattern.
         Similarly, if the rule fires on  <code style="font-size: 13px;">match="section"</code>, then you can't access the title in the rule action (<code>select="title"</code>) because the action too must be motionless. In some cases a workaround is to have
         an accumulator that matches the text nodes (<code>match="section/title/text()[.='introduction']"</code>) but that doesn't work if section titles can have mixed content.
         </p>
      <p>
         
         
         It turns out there's a simple fix, which I call a <i>capturing accumulator rule</i>. A capturing accumulator rule is indicated by the extension attribute <code>&lt;xsl:accumulator-rule saxon:capture="yes" phase="end"&gt;</code>, which will always be a rule that fires on an end-element tag. For a capturing rule,
         the background process listens to all the parser events that occur between the start
         tag and the end tag, and uses these to build a snapshot copy of the node. A snapshot
         copy is like the result of the fn:snapshot function - it's a deep copy of the matched
         node, with ancestor elements and their attributes tagged on for good measure. This
         snapshot copy is then available to the action part of the rule processing the end
         tag. The match patterns that trigger the accumulator rule still need to be motionless,
         but the action part now has access to a complete copy of the element (plus its ancestor
         elements and their attributes).
         </p>
      <p>
         Here's an example. Suppose you've got a large document like the XSLT specification,
         and you want to produce a sorted glossary at the end, and you want to do it all in
         streamed mode. Scattered throughout the document are term definitions like this:
         </p>
      <pre>&lt;termdef id="dt-stylesheet" term="stylesheet"&gt;A  &lt;term&gt;stylesheet&lt;/term&gt; consists of one or more packages: specifically, one
   &lt;termref def="dt-top-level-package"&gt;top-level package&lt;/termref&gt; and zero or
   more &lt;termref def="dt-library-package"&gt;library packages&lt;/termref&gt;.&lt;/termdef&gt;</pre>
      <p>
         
         Now we can write an accumulator which simply accumulates these term definitions as
         they are encountered:
         
         
         </p>
      <pre>&lt;xsl:accumulator name="terms" streamable="yes"&gt;
    &lt;xsl:accumulator-rule match="termdef" phase="end" select="($value, .)" saxon:capture="yes"/&gt;
&lt;/xsl:accumulator&gt;</pre>
      <p>
         (the <code>select</code> expression here takes the existing value of the accumulator, <code>$value</code>, and appends the snapshot of the current termdef element, which is available as the
         context item ".")
         </p>
      <p>
         And now, at the end of the processing, we can output the glossary like this:
         
         </p>
      <pre>&lt;xsl:template match="/" mode="streamable-mode"&gt;
    &lt;html&gt; 
        &lt;!-- main foreground processing goes here --&gt;
        &lt;xsl:apply-templates mode="#current"/&gt;
        &lt;!-- now output the glossary --&gt;
        &lt;div id="glossary" class="glossary"&gt;
            &lt;xsl:apply-templates select="accumulator-after('terms')" mode="glossary"&gt;
                &lt;xsl:sort select="@term" lang="en"/&gt;
            &lt;/xsl:apply-templates&gt;
        &lt;/div&gt;
    &lt;/html&gt;
&lt;/xsl:template&gt;</pre>
      <p>
         The value of the accumulator is a list of snapshots of termdef elements, and because
         these are snapshots, the processing at this point does not need to be streamable (snapshots
         are ordinary trees held in memory).
         </p>
      <p>
         The amount of memory needed to accomplish this is whatever is needed to hold the glossary
         entries. This follows the design principle behind XSLT 3.0 streaming, which was not
         to do just those things that required zero working memory, but to enable the programmer
         to do things that weren't purely streamable, while having control over the amount
         of memory needed.
         </p>
      <p>
         I think it's hard to find an easy way to tackle this particular problem without the
         new feature of capturing accumulator rules, so I hope it will prove a useful extension.
         </p>
      <p>
         I've implemented this for Saxon 9.9. Interestingly, it only took about 25 lines of
         code: half a dozen to enable the new extension attribute, half a dozen to allow it
         to be exported to SEF files and re-imported, two or three to change the streamability
         analysis, and a few more to invoke the existing streaming implementation of the snapshot
         function from the accumulator watch code. Testing and documenting the feature was
         a lot more work than implementing it.
         </p>
      <p>
         Here's a complete stylesheet that fleshes out the creation of a (skeletal) glossary:
         </p>
      <pre>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;xsl:package
  name="http://www.w3.org/xslt30-test/accumulator/capture-203"
  package-version="1.0"
  declared-modes="no"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:f="http://accum001/"
  xmlns:saxon="http://saxon.sf.net/"
  exclude-result-prefixes="#all" version="3.0"&gt;

  &lt;!-- Stylesheet to produce a glossary using capturing accumulators --&gt;
  
  &lt;!-- The source document is a W3C specification in xmlspec format, containing
    term definitions in the form &lt;termdef term="banana"&gt;A soft &lt;termref def="fruit"/&gt;&lt;/termdef&gt; --&gt;
  
  &lt;!-- This test case shows the essential principles of how to render such a document
    in streaming mode, with an alphabetical glossary of defined terms at the end --&gt;
  
  &lt;xsl:param name="streamable" static="yes" select="'yes'"/&gt;
  
  &lt;xsl:accumulator name="glossary" as="element(termdef)*" initial-value="()" streamable="yes"&gt;
    &lt;xsl:accumulator-rule match="termdef" phase="end" saxon:capture="yes" select="($value, .)"/&gt;
  &lt;/xsl:accumulator&gt;

  &lt;xsl:mode streamable="yes" on-no-match="shallow-skip" use-accumulators="glossary"/&gt;
  
  &lt;xsl:template name="main"&gt;
    &lt;xsl:source-document href="xslt.xml" streamable="yes" use-accumulators="glossary"&gt;
      &lt;xsl:apply-templates select="."/&gt;
    &lt;/xsl:source-document&gt;
  &lt;/xsl:template&gt;
  
 &lt;xsl:template match="/"&gt;
    &lt;out&gt;
      &lt;!-- First render the body of the document --&gt;
      &lt;xsl:apply-templates/&gt;
      &lt;!-- Now generate the glossary --&gt;
      &lt;table&gt;
        &lt;tbody&gt;
          &lt;xsl:apply-templates select="accumulator-after('glossary')" mode="glossary"&gt;
            &lt;xsl:sort select="@term" lang="en"/&gt;
          &lt;/xsl:apply-templates&gt;
        &lt;/tbody&gt;
      &lt;/table&gt;
    &lt;/out&gt;
  &lt;/xsl:template&gt;
  
  &lt;xsl:template match="div1|inform-div1"&gt;
    &lt;div id="{@id}"&gt;
      &lt;xsl:apply-templates/&gt;
    &lt;/div&gt;
  &lt;/xsl:template&gt;
  
  &lt;!-- Main document processing: just output the headings --&gt;
  
  &lt;xsl:template match="div1/head | inform-div1/head"&gt;
    &lt;xsl:attribute name="title" select="."/&gt;
  &lt;/xsl:template&gt;
  
  &lt;!-- Glossary processing --&gt;
  
  &lt;xsl:mode name="glossary" streamable="no"/&gt;
  
  &lt;xsl:template match="termdef" mode="glossary"&gt;
    &lt;tr&gt;
      &lt;td&gt;
        &lt;xsl:value-of select="@term"/&gt;
      &lt;/td&gt;
      &lt;td&gt;
        &lt;xsl:value-of select="."/&gt;
      &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/xsl:template&gt;

&lt;/xsl:package&gt;</pre>
   </div></content></entry><entry><title>Diagnostics on Type Errors</title><link href="https://blog.saxonica.com/mike/2018/03/diagnostics-on-type-errors.html" rel="alternate" type="text/html"/><id>https://blog.saxonica.com/mike/2018/03/diagnostics-on-type-errors.html</id><published>2018-03-16T15:50:27Z</published><content type="xhtml" xml:base="https://blog.saxonica.com/mike/2018/03/diagnostics-on-type-errors.html"><div xmlns="http://www.w3.org/1999/xhtml">
      
      <p>Providing good diagnostics for programming errors has always been a high priority
         in Saxon, second only to conformance with the W3C specifications. One important area
         of diagnostics is reporting on type errors: that is, cases where a particular context
         requires a value of a given type, and the supplied value is the wrong type. A classic
         example would be providing a string as the first argument to format-date(), which
         requires an xs:date to be supplied.
         </p>
      <p>
         Of course, the more programmers follow the discipline of declaring the expected types
         of function parameters and variables, the more helpful the compiler can be in diagnosing
         programming errors caused by supplying the wrong type of value.<br/>
         Type errors can be detected statically or dynamically. Saxon uses "optimistic type
         checking". 
         </p>
      <p>
         At compile time, it a value of type R is required in a particular context, and the
         expression appearing in that context is E, then the compiler attempts to infer the
         static type of expression E: call this S. Sometimes this is straightforward, for example
         if E is a call on the node-name() function, then it knows that S is xs:QName. In other
         case the compiler has to be smarter: for example it knows that the static type of
         a call on remove() is the same as the static type of the first argument, with an adjustment
         to the occurrence indicator.
         
         </p>
      <p>
         Optimistic type checking reports an error at compile time only if there is nothing
         in common between the required type R and the inferred static type of E: that is,
         if there is no overlap between the set of instances of the two types. That would mean
         that a run-time failure is inevitable (assuming the code actually gets executed),
         and the W3C specifications allow early reporting of such an error.
         </p>
      <p>
         There's another interesting case where the types overlap only to the extent that both
         allow an empty sequence: for example if the required type is (xs:string*) and the
         supplied type is (xs:integer*). That's almost certainly an error, but W3C doesn't
         allow an error to be reported here because there is a faint chance that execution
         could succeed. So Saxon reports this as a warning. With maps and arrays, incidentally,
         there are analogous situations where the only overlap is an empty map or array, but
         Saxon isn't yet handling that case specially.
         </p>
      <p>
         If the types aren't completely disjoint, there are two other possibilities: the required
         type R might subsume the supplied type S, meaning that no run-time type checking is
         needed because the call will always succeed. The other possibility is that the types
         overlap: evaluating the supplied expression E might or might not produce a value that
         matches the required type R. In this case Saxon generates code to perform run-time
         type checking. (This is one reason why declaring the types of parameters and variables
         is such good practice: the code runs faster because there is no unnecessary run-time
         checking.)
         </p>
      <p>
         Until recently, the error message for a type error takes the form:
         </p>
      <p>
         Required item type of CCC is RRR; supplied value has item type SSS
         </p>
      <p>
         For example:
         </p>
      <p>
         <b>Required item type of first argument to format-date() is xs:date; supplied value has
            item type xs:string</b>
         </p>
      <p>
         which works pretty well in most cases. However, I'm finding that as I write more complex
         code involving maps and arrays, it's no longer good enough. The problem is that as
         the types become more complex, simply giving the required and actual types isn't enough
         to make it clear why they are incompatible. You end up with messages like this one:
         </p>
      <p>
         
         <b>Required item type of first argument of local:x() is map(xs:integer, xs:date); </b><b>supplied value has item type map(xs:anyAtomicType, xs:date).</b>
         
         </p>
      <p>
         where an expert user can probably work out that the problem is that the supplied map
         contains an entry whose key is not an integer; but it doesn't exactly point clearly
         to the source of the problem.
         </p>
      <p>
         The problem comes to a head particularly when tuple types are used (see <a href="/mike/2016/09/tuple-types-and-type-aliases.html">here</a>). If the required type is a tuple type, reporting the supplied type as a map type
         is particularly unhelpful.
         </p>
      <p>
         I'm therefore changing the approach: instead of reporting on the supplied type of
         the value (or the inferred type of the expression, in the case of static errors),
         I'm reporting an explanation of why it doesn't match. Here's the new version of the
         message:
         </p>
      <p>
         
         <b>The required item type of the first argument of local:x() is map(xs:integer, </b><b>xs:date); the supplied value map{xs:date("2018-03-16Z"):5, "x":3} does not match.
            The map </b><b>contains a key (xs:date("2018-03-16Z")) of type xs:date that is not an instance of
            the </b><b>required type xs:integer.</b>
         
         </p>
      <p>
         So firstly, I'm outputting the actual value, or an abbreviated form of it, rather
         than just its type (that only works, of course, for run-time errors). And secondly,
         I'm highlighting how the type-checker worked out that the value doesn't match the
         required type: it's saying explicitly which rule was broken.
         </p>
      <p>
         (Another minor change you can see here is that I'm making more effort to write complete
         English sentences.)
         </p>
      <p>
         This doesn't just benefit the new map and array types, you can also see the effect
         with node types. For example, if the required type is document-node(element(foo)),
         you might see the message:
         </p>
      <p>
         
         <b>The required item type of the first argument of local:x() is </b><b>document-node(element(Q{}foo)); the supplied value doc() does not match. The supplied </b><b>document node has an element child (&lt;bar&gt;) that does not satisfy the element test.
            The </b><b>node has the wrong name.</b>
         
         </p>
      <p>
         Another change I'm making is to distribute type-checking into a sequence constructor.
         At present, if a function is defined to return (say) a list of element nodes, and
         the function body contains a sequence of a dozen instructions, one of which returns
         a text node, you get a message saying that the type of the function result is wrong,
         but it doesn't pinpoint exactly why. By distributing the type checking (applying the
         principle that if the function must return element nodes, then each of the instructions
         must return element nodes) we can (a) identify the instruction in error much more
         precisely, and (b) avoid the run-time cost of checking the results of those instructions
         that we know statically are OK.
         </p>
      <p>
         Interestingly, all these changes were stimulated by my own recent experience in writing
         a complex stylesheet. I described the plans for this <a href="/mike/2018/02/could-we-write-an-xsd-schema-processor-in-xslt.html">here</a> and the coding has now been completed (I'll report on the outcome later). It's a
         classic case of dogfood: if you use your own products in anger, you find ways of improving
         them that you wouldn't have thought of otherwise, and that users wouldn't have suggested
         because they don't know what's possible.
         </p>
   </div></content></entry><entry><title>Could we write an XSD Schema Processor in XSLT?</title><link href="https://blog.saxonica.com/mike/2018/02/could-we-write-an-xsd-schema-processor-in-xslt.html" rel="alternate" type="text/html"/><id>https://blog.saxonica.com/mike/2018/02/could-we-write-an-xsd-schema-processor-in-xslt.html</id><published>2018-02-10T18:58:46Z</published><content type="xhtml" xml:base="https://blog.saxonica.com/mike/2018/02/could-we-write-an-xsd-schema-processor-in-xslt.html"><div xmlns="http://www.w3.org/1999/xhtml">
      
      <p>Many computing platforms are not
         well-served by up to date XML technology, and in consequence Saxonica
         has been slowly increasing its coverage of the major platforms:
         extending from Java to .NET, C++, PHP, Javascript using a variety of
         technical approaches. This makes it desirable to implement as much as
         possible using portable languages, and if we want to minimize our
         dependence on third-party technologies (IKVMC, for example, is now
         effectively unsupported) we should be writing in our own languages,
         notably XSLT.</p>
      <p>This note therefore asks the question,
         could one write an XSD Schema 1.1 processor in XSLT?</p>
      <p>In fact a schema processor has two
         parts, compile time (compiling schema documents into the schema
         component model and SCM) and run-time (validating an instance
         document using the SCM).
         </p>
      <p>The first part, compiling, seems to
         pose no intrinsic difficulty. Some of the rules and constraints that
         need to be enforced are fairly convoluted, but the only really tricky
         part is compiling grammars into finite-state-machines, and checking
         grammars (or the resulting finite-state-machine) for conformance with
         rules such as the Unique Particle Attribution constraint. But since
         we already have a tool (written in Java) for compiling schemas into
         an XML-based SCM file, and since it wouldn't really inconvenience
         users too much for this tool to be invoked via an HTTP interface, the
         priority for a portable implementation is really the run-time part of
         the processor rather than the compile-time part. (Note that this means ignoring xsi:schemaLocation,
         since that effectively causes the run-time validator to invoke the schema compiler.)</p>
      <p>There are two ways one could envisage
         implementing the run-time part in XSLT: either with a universal
         stylesheet that takes the SCM and the instance document as inputs, or
         by generating a custom XSLT stylesheet from the SCM, rather as is
         done with Schematron. For the moment I'll keep an open mind which of
         these two approaches is preferable.</p>
      <p>Ideally, the XSLT stylesheet would use
         streaming so the instance document being validated does not need to
         fit in memory. We'll bear this requirement in mind as we look at the
         detail.</p>
      <p>The XSLT code, of course, cannot rely
         on any services from a schema processor, so it cannot be
         schema-aware.</p>
      <p>Let's look at the main jobs the
         validator has to do.</p>
      <p><b>Validating strings against simple types</b></p>
      <p>Validating against a primitive type can
         be done simply using the XPath castable operator.</p>
      <p>Validating against a simple type
         derived by restriction involves checking the various facets. For the
         most part, the logic of each facet is easily expressed in XPath.
         There are a few exceptions:</p>
      <p>
         
         
         
         <ul>
            <li>
               
               
               <p>Patterns (regular expressions).
                  The XPath regular expression syntax is a superset of the XSD syntax.
                  To evaluate XSD regular expressions, we either need some kind of
                  extension to the XPath matches() function, or we need to translate
                  XSD regular expressions into XPath regular expressions. This
                  translation is probably not too difficult. It mainly involves
                  rejecting some disallowed constructs (such as back-references,
                  non-capturing groups, and reluctant quantifiers), and escaping "^"
                  and "$" with a backslash.</p>
               </li>
            <li>
               
               
               <p>Length facets for hexBinary and
                  base64Binary. Base646Binary can be cast to hexBinary, and the length
                  of the value in octets can be computed by converting to string and
                  dividing the string length by 2.</p>
               </li>
         </ul>
         
         </p>
      <p>Validating against a list type can be
         achieved by tokenizing, and testing each token against the item type.</p>
      <p>Validating against a union type can be
         achieved by validating against each member type (and also validing
         against any constraining facets defined at the level of the union
         itself).</p>
      <p><b>Validating elements against complex
            types</b></p>
      <p>The only difficult case here is complex
         content. It should be possible to achieve this by iterating over the
         child nodes using xsl:iterate, keeping the current state (in the FSM)
         as the value of the iteration parameter. On completion the element is
         valid if the state is a final state. As each element is processed, it
         needs to be checked against the state of its parent element's FSM,
         and in addition a new validator is established for validating its
         children. This is all streamable.</p>
      <p><b>Assertions and Conditional Type
            Assignment</b></p>
      <p>Evaluating XPath expressions can be
         achieved using xsl:evaluate. The main difficulty is setting up the
         node-tree to which xsl:evaluate is applied. This needs to be a copy
         of the original source subtree, to ensure that the assertion cannot
         stray outside the relevant subtree. Making this copy consumes the
         source subtree, which makes streaming tricky: however, the ordinary
         complex type validation can also happen on the copy, so I think
         streaming is possible.</p>
      <p><b>Identity constraints (unique, key,
            keyref)</b></p>
      <p>This is where streaming really gets
         quite tricky - especially given the complexity of the specification
         for those rare keyref cases where the key is defined on a different
         element from the corresponding keyref.</p>
      <p>The obvious XSLT mechanism here is
         accumulators. But accumulator rules are triggered by patterns, and
         defining the patterns that correspond to the elements involved in a
         key definition is tricky. For example if sections nest recursively, a
         uniqueness constraint might say that for every section, its child
         section elements must have unique @section-number attributes. A
         corresponding accumulator would have to maintain a stack of sections,
         with a map of section numbers at each level of the stack, and the
         accumulator rule for a section would need to check the section number
         of that section at the current level, and start a new level.</p>
      <p>A further complication is that there
         may be multiple (global and/or local) element declarations with the
         same name, with different unique / key / keyref constraints. Deciding
         which of these apply by means of XSLT pattern matching is certainly
         difficult and may be impossible.</p>
      <p>The multiple xs:field elements within a
         constraint do not have to match components of the key in document
         order, but a streamed implementation would still be possible using
         the map constructor, which allows multiple downward selections -
         provided that the xs:field selector expressions are themselves
         streamable, which I think is probably always the case.</p>
      <p>The problem of streamability could
         possibly be solved with some kind of dynamic pipelining. The "main"
         validation process, when it encounters a start tag, is able to
         establish which element declaration it belongs to, and could in
         principle spawn another transformation (processing the same input
         stream) for each key / unique constraint defined in that element
         declaration: a kind of dynamic xsl:fork.</p>
      <p>I think as a first cut it would
         probably be wise not to attempt streaming in the case of a schema
         that uses unique / key / keyref constraints. More specifically, if
         any element has such constraints, it can be deep-copied, and
         validation can then switch to the in-memory subtree rather than the
         original stream. After all, we have no immediate plans to implement
         streaming other than in the Java product, and that will inevitably
         make an XSLT-based schema processor on other platforms unstreamed
         anyway.</p>
      <p><b>Outcome of validation</b></p>
      <p>There are two main scenarios we should
         support: validity checking, and type annotation. With validity
         checking we want to report many invalidities in a single validation
         episode, and the main output is the validation report. With type
         annotation, the main output is a validated version of the instance
         document, and a single invalidity can cause the process to terminate
         with a dynamic error.</p>
      <p>It is not possible for a
         non-schema-aware stylesheet to add type annotations to the result
         tree without some kind of extensions. The XSLT language only allows
         type annotations to be created as the result of schema validation. So
         we will need an extension for this purpose: perhaps a
         saxon:type-annotation="QName" attribute on instructions
         such as xsl:element, xsl:copy, xsl:attribute.</p>
      <p>For reporting validation errors, it's
         important to report the location of the invalidity. This also
         requires extensions, such as saxon:line-number().</p>
      <p><b>Conclusion</b></p>
      <p>I don't think there are any serious
         obstacles to writing a validation engine in XSLT. Making it
         streamable is harder, especially for integrity constraints. A couple
         of extensions are needed: the ability to add type annotations to the
         result tree, and the ability to get line numbers of nodes in the
         source.</p>
      <p>I still have an open mind about whether
         a universal stylesheet should be used, or a generated stylesheet for
         a particular schema.</p>
   </div></content></entry><entry><title>Transforming JSON</title><link href="https://blog.saxonica.com/mike/2017/11/transforming-json.html" rel="alternate" type="text/html"/><id>https://blog.saxonica.com/mike/2017/11/transforming-json.html</id><published>2017-11-13T13:02:13Z</published><content type="xhtml" xml:base="https://blog.saxonica.com/mike/2017/11/transforming-json.html"><div xmlns="http://www.w3.org/1999/xhtml">
      
      <p>In my [conference paper at XML Prague](https://www.saxonica.com/papers/xmlprague-2016mhk.pdf)
         in 2016 I examined a couple of use cases for transforming JSON structures using XSLT
         3.0. The overall conclusion was not particularly encouraging: the easiest way to achieve
         the desired results was to convert the JSON to XML, transform the XML, and then convert
         it back to JSON.
         </p>
      <p>
         Unfortunately this study came too late to get any new features into XSLT 3.0. However,
         I've been taking another look at the use cases to see whether we could design language
         extensions to handle them, and this is looking quite encouraging.
         </p>
      <p><b>Use case 1: bulk update</b></p>
      <p>We start with the JSON document</p>
      <pre>[ {
  "id": 3, "name": "A blue mouse", "price": 25.50,
  "dimensions": {"length": 3.1, "width": 1.0, "height": 1.0},
  "warehouseLocation": {"latitude": 54.4, "longitude": -32.7 }},
  {
  "id": 2, "name": "An ice sculpture", "price": 12.50,
  "tags": ["cold", "ice"],
  "dimensions": {"length": 7.0, "width": 12.0, "height": 9.5 },
  "warehouseLocation": {"latitude": -78.75, "longitude": 20.4 }
} ]</pre>
      <p>and the requirement: for all products having the tag "ice", increase the price by
         10%, leaving all other data unchanged.
         I've prototyped a new XSLT instruction that allows this to be done as follows:</p>
      <pre>&lt;saxon:deep-update
root="json-doc('input.json')
select=" ?*[?tags?* = 'ice']"
action="map:put(., 'price', ?price * 1.1)"/&gt;</pre>
      <p>How does this work?
         </p>
      <p>
         First the instruction evaluates the <code>root</code> expression, which in this case returns
         the map/array representation of the input JSON document. With this root item as context
         item, it then evaluates the <code>select</code> expression to obtain a sequence of contained
         maps or arrays to be updated: these can appear at any depth under the root item. With
         each of these selected maps or arrays as the context item, it then evaluates the action
         expression, and uses the returned value as a replacement for the selected map or array.
         This update then percolates back up to the root item, and the result of the instruction
         is a map or array that is the same as the original except for the replacement of the
         selected items.
         </p>
      <p>
         The magic here is in the way that the update is percolated back up to the root. Because
         maps and arrays are immutable and have no persistent identity, the only way to do
         this is to keep track of the maps and arrays selected en-route from the root item
         to the items selected for modification as we do the downward selection, and then modify
         these maps and arrays in reverse order on the way back up. Moreover we need to keep
         track of the cases where multiple updates are made to the same containing map or array.
         All this magic, however, is largely hidden from the user. The only thing the user
         needs to be aware of is that the select expression is constrained to use a limited
         set of constructs when making downward selections.
         </p>
      <p>
         The select expression <code>select="?*[?tags?* = 'ice']"</code>
         perhaps needs a little bit of
         explanation. The root of the JSON tree is an array of maps, and the initial <code>?*</code> turns
         this into a sequence of maps. We then want to filter this sequence of maps to include
         only those where the value of the "tags" field is an array containing the string "ice"
         as one of its members. The easiest way to test this predicate is to convert the value
         from an array of strings to a sequence of strings (so <code>?tags?*</code>) and then use the
         XPath existential "=" operator to compare with the string "ice".
         </p>
      <p>
         The action expression <code>map:put(., 'price', ?price * 1.1)</code> takes as input the selected
         map, and replaces it with a map in which the <code>price</code> entry is replaced with a new
         entry having the key "price" and the associated value computed as the old price multiplied
         by 1.1.
         </p>
      <p><b>Use case 2: Hierarchic Inversion</b></p>
      <p>The second use case in the XML Prague 2016 paper was a
         hierarchic inversion (aka grouping) problem. Specifically: we'll
         look at a structural transformation changing a JSON structure
         with information about the students enrolled for each course to
         its inverse, a structure with information about the courses for
         which each student is enrolled.
         </p>
      <p>
         Here is the input dataset:
         </p>
      <pre>[
  {
    "faculty": "humanities",
    "courses": [
      {
        "course": "English",
        "students": [
          {
            "first": "Mary",
            "last": "Smith",
            "email": "mary_smith@gmail.com"
          },
          {
            "first": "Ann",
            "last": "Jones",
            "email": "ann_jones@gmail.com"
          }
        ]
      },
      {
        "course": "History",
        "students": [
          {
            "first": "Ann",
            "last": "Jones",
            "email": "ann_jones@gmail.com"
          },
          {
            "first": "John",
            "last": "Taylor",
            "email": "john_taylor@gmail.com"
          }
        ]
      }
    ]
  },
  {
    "faculty": "science",
    "courses": [
      {
        "course": "Physics",
        "students": [
          {
            "first": "Anil",
            "last": "Singh",
            "email": "anil_singh@gmail.com"
          },
          {
            "first": "Amisha",
            "last": "Patel",
            "email": "amisha_patel@gmail.com"
          }
        ]
      },
      {
        "course": "Chemistry",
        "students": [
          {
            "first": "John",
            "last": "Taylor",
            "email": "john_taylor@gmail.com"
          },
          {
            "first": "Anil",
            "last": "Singh",
            "email": "anil_singh@gmail.com"
          }
        ]
      }
    ]
  }
]</pre>
      <p>The goal is to produce a list of students, sorted by last name then irst name, each
         containing a list of courses taken by that student, like this:
         </p>
      <pre>[
  { "email": "anil_singh@gmail.com",
    "courses": ["Physics", "Chemistry" ]},
  { "email": "john_taylor@gmail.com",
    "courses": ["History", "Chemistry" ]},
  ...
]</pre>
      <p>The classic way of handling this is in two phases: first reduce the hierarchic input
         to a flat sequence in which all the required information is contained at one level,
         and then apply grouping to this flat sequence.
         </p>
      <p>
         To achieve the flattening we introduce another new XSLT instruction:
         </p>
      <p>
         
         
         
         <pre>&lt;saxon:tabulate-maps
root="json-doc('input.json')"
select="?* ! map:find(., 'students)?*"/&gt;</pre>
         
         
         
         <p>Again the <code>root</code> expression delivers a representation of the JSON document as an array
            of maps. The <code>select</code> expression first selects these maps ("?*"), then for each one
            it calls map:find() to get an array of maps each representing a student. The result
            of the instruction is a sequence of maps corresponding to these student maps in the
            input, where each output map contains not only the fields present in the input (first,
            last, email), but also fields inherited from parents and ancestors (faculty, course).
            For good measure it also contains a field _keys containing an array of keys representing
            the path from root to leaf, but we don't actually use that in this example.
            </p>
         
         <p>
            Once we have this flat structure, we can construct a new hierarchy using XSLT grouping:
            </p>
         
         
         <pre>&lt;xsl:for-each-group select="$students" group-by="?email"&gt;
&lt;xsl:map&gt;
&lt;xsl:map-entry key="'email'" select="?email"/&gt;
&lt;xsl:map-entry key="'first'" select="?first"/&gt;
&lt;xsl:map-entry key="'last'" select="?last"/&gt;
&lt;xsl:map-entry key="'courses'"&gt;
&lt;saxon:array&gt;
&lt;xsl:for-each select="current-group()"&gt;
&lt;saxon:array-member select="?course"/&gt;
&lt;/xsl:for-each&gt;
&lt;/saxon:array&gt;
&lt;/xsl:map-entry&gt;
&lt;/xsl:map&gt;
&lt;/xsl:for-each-group&gt;</pre>
         
         
         
         <p>This can then be serialized using the JSON output method to produce to required output.
            </p>
         
         <p>
            Note: the <code>saxon:array</code> and <code>saxon:array-member</code> instructions already exist in Saxon
            9.8. They fill an obvious gap in the XSLT 3.0 facilities for handling arrays - a gap
            that exists largely because the XSL WG was unwilling to create a dependency XPath
            3.1.
            </p>
         
         
         
         <p><b>Use Case 3: conversion to HTML</b></p>
         
         
         
         <p>This use case isn't in the XML Prague paper, but is included here for completeness.
            </p>
         
         <p>
            The aim here is to construct an HTML page containing the information from a JSON document,
            without significant structural alteration. This is a classic use case for the recursive
            application of template rules, so the aim is to make it easy to traverse the JSON
            structure using templates with appropriate match patterns.
            </p>
         
         <p>
            Unfortunately, although the XSLT 3.0 facilities allow patterns that match maps and
            arrays, they are cumbersome to use. Firstly, the syntax is awkward:
            </p>
         
         
         <pre>match=".[. instance of map(...)]"</pre>
         </p>
      <p>
         We can solve this with a Saxon extension allowing the syntax
         </p>
      <pre>match="map()"</pre>
      <p>Secondly, the type of a map isn't enough to distinguish one map from another. To identify
         a map representing a student, for example, we aren't really interested in knowing
         that it is a <code>map(xs:string, item()*)</code>. What we need to know is that it has fields
         (email, first, last). Fortunately another Saxon extension comes to our aid: tuple
         types, described here: <a href="https://blog.saxonica.com/mike/2016/09/tuple-types-and-type-aliases.html">https://blog.saxonica.com/mike/2016/09/tuple-types-and-type-aliases.html</a>
         With tuple types we can change the match pattern to
         </p>
      <pre>match="tuple(email, first, last)"</pre>
      <p>Even better, we can use type aliases:</p>
      <pre>&lt;saxon:type-alias name="student" as="tuple(email, first, last)"/&gt;
&lt;xsl:template match="~student"&gt;...&lt;/xsl:template&gt;</pre>
      <p>With this extension we can now render this input JSON into HTML using the stylesheet:</p>
      <pre>&lt;?xml version="1.0" encoding="utf-8"?&gt;

&lt;xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:saxon="http://saxon.sf.net/"
exclude-result-prefixes="#all"
expand-text="yes"

&lt;saxon:type-alias name="faculty" type="tuple(faculty, courses)"/&gt;
&lt;saxon:type-alias name="course" type="tuple(course, students)"/&gt;
&lt;saxon:type-alias name="student" type="tuple(first, last, email)"/&gt;

&lt;xsl:template match="~faculty"&gt;
&lt;h1&gt;{?faculty} Faculty&lt;/h1&gt;
&lt;xsl:apply-templates select="?courses?*"/&gt;
&lt;/xsl:template&gt;

&lt;xsl:template match="~course"&gt;
&lt;h2&gt;{?course} Course&lt;/h2&gt;
&lt;p&gt;List of students:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Email&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;xsl:apply-templates select="?students?*"&gt;
&lt;xsl:sort select="?last"/&gt;
&lt;xsl:sort select="?first"/&gt;
&lt;/xsl:apply-templates&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/xsl:template&gt;

&lt;xsl:template match="~student"&gt;
&lt;tr&gt;
&lt;td&gt;{?first} {?last}&lt;/td&gt;
&lt;td&gt;{?email}&lt;/td&gt;
&lt;/tr&gt;
&lt;/xsl:template&gt;

&lt;xsl:template name="xsl:initial-template"&gt;
&lt;xsl:apply-templates select="json-doc('courses.json')"/&gt;
&lt;/xsl:template&gt;

&lt;/xsl:stylesheet&gt;</pre>
      <p><b>Conclusions</b></p>
      <p>With only the facilities of the published XSLT 3.0 recommendation, the easiest way
         to transform JSON is often to convert it first to XML node trees, and then use the
         traditional XSLT techniques to transform the XML, before converting it back to JSON.
         </p>
      <p>
         With a few judiciously chosen extensions to the language, however, a wide range of
         JSON transformations can be achieved natively.
         </p>
   </div></content></entry><entry><title>Bugs: How well are we doing?</title><link href="https://blog.saxonica.com/mike/2017/02/bugs-how-well-are-we-doing.html" rel="alternate" type="text/html"/><id>https://blog.saxonica.com/mike/2017/02/bugs-how-well-are-we-doing.html</id><published>2017-02-05T17:36:01Z</published><content type="xhtml" xml:base="https://blog.saxonica.com/mike/2017/02/bugs-how-well-are-we-doing.html"><div xmlns="http://www.w3.org/1999/xhtml">
      
      <p>We're about to ship another Saxon 9.7 maintenance release, with another 50 or so bug
         clearances. The total number of patches we've issued since 9.7 was released in November
         2015 has now reached almost 450. The number seems frightening and the pace is relentless.
         But are we getting it right, or are we getting it badly wrong?
         </p>
      <p>
         There are frequently-quoted but poorly-sourced numbers you can find on the internet
         suggesting a norm of 10-25 bugs per thousand lines of code. Saxon is 300,000 lines
         of (non-comment) code, so that would suggest we can expect a release to have 3000
         to 7500 bugs in it. One one measure that suggests we're doing a lot better than the
         norm. Or it could also mean that most of the bugs haven't been found yet.
         </p>
      <p>
         I'm very sceptical of such numbers. I remember a mature product in ICL that was been
         maintained by a sole part-time worker, handling half a dozen bugs a month. When she
         went on maternity leave, the flow of bugs magically stopped. No-one else could answer
         the questions, so users stopped sending them in. The same happens with Oracle and
         Microsoft. I submitted a Java bug once, and got a response 6 years later saying it
         was being closed with no action. When that happens, you stop sending in bug reports.
         So in many ways, a high number of bug reports doesn't mean you have a buggy product,
         it means you have a responsive process for responding to them. I would hate the number
         of bug reports we get to drop because people don't think there's any point in submitting
         them.
         </p>
      <p>
         And of course the definition of what is a bug is completely slippery. Very few of
         the bug reports we get are completely without merit, in the sense that the product
         is doing exactly what it says on the tin; at the same time, rather few are incontrovertible
         bugs either. If diagnostics are unhelpful, is that a bug?
         </p>
      <p>
         The only important test really is whether our users are satisfied with the reliability
         of the product. We don't really get enough feedback on that at a high level. Perhaps
         we should make more effort to find out; but I so intensely hate completing customer
         satisfaction questionnaires myself that I'm very reluctant to inflict it on our users.
         Given that open source users outnumber commercial users by probably ten-to-one, and
         that the satisfaction of our open source users is just as important to us as the satisfaction
         of our commercial customers (because it's satisfied open source users who do all the
         sales work for us); and given that we don't actually have any way of "reaching out"
         to our open source users (how I hate the marketing jargon); and given that we really
         wouldn't know what to differently if we discovered that 60% of our users were "satisfied
         or very satisfied": I don't really see very much value in the exercise. But I guess
         putting a survey form on the web site wouldn't be difficult, some people might interpret
         it as a signal that we actually care.
         </p>
      <p>
         With 9.7 there was a bit of a shift in policy towards fixing bugs pro-actively (more
         marketing speak). In particular, we've been in a phase where the XSLT and XQuery specs
         were becoming very stable but more test cases were becoming available all the time
         (many of them, I might add, contributed by Saxonica - often in reaction to queries
         from our users). So we've continuously been applying new tests to the existing release,
         which is probably a first. Where a test showed that we were handling edge cases incorrectly,
         and indeed when the spec was changed in little ways under our feet, we've raised bugs
         and fixes to keep the conformance level as high as possible (while also maintaining
         compatibility). So we've shifted the boundary a little between feature changes (which
         traditionally only come in the next release), and bug fixes, which come in a maintenance
         release. That shift also helps to explain why the gap between releases is becoming
         longer - though the biggest factor holding us back, I think, is the ever-increasing
         amount of testing that we do before a release.
         </p>
      <p>
         Fixing bugs pro-actively (that is before any user has hit the bug) has the potential
         to improve user satisfaction if it means that they never do hit the bug. I think it's
         always as well to remember also that for every user who reports a bug there may be
         a dozen users who hit it and don't report it. One reason we monitor StackOverflow
         is that a lot of users feel more confident about reporting a problem there, rather
         than reporting it directly to us. Users know that their knowledge is limited and they
         don't want to make fools of themselves, and you need a high level of confidence to
         tell your software vendor that you think the product is wrong. 
         </p>
      <p>
         On the other hand, destabilisation is a risk. A fix in one place will often expose
         a bug somewhere else, or re-awaken an old bug that had been laid to rest. As a release
         becomes more mature, we try to balance the benefits of fixing problems with the risk
         of de-stabilisation.
         </p>
      <p>
         So, what about testing? Can we say that because we've fixed 450 bugs, we didn't run
         enough tests in the first place?
         </p>
      <p>
         Yes, in a sense that's true, but how many more tests would have had to write in order
         to catch them? We probably run about a million test cases (say, 100K tests in an average
         of ten product configurations each) and these days the last couple of months before
         a major release are devoted exclusively to testing. (I know that means we don't do
         enough continuous testing. But sorry, it doesn't work for me. If we're doing something
         radical to the internals of the product then things are going to break in the process,
         and my style is to get the new design working while it's still fresh in my head, then
         pick up the broken pieces later. If everything had to work in every nightly build,
         we would never get the radical things done. That's a personal take, and of course
         what works with a 3-4 person team doesn't necessarily work with a larger project.
         We're probably pretty unusual in developing a 300Kloc software package with 3-4 people,
         so lots of our experience might not extrapolate.)
         </p>
      <p>
         We've had a significant number of bug reports this time on performance regression.
         (This is of course another area where it's arguable whether it's a bug or not. Sometimes
         we will change the design in a way that we know benefits some workloads at the expense
         of others.) Probably most of these are extreme scenarios, for example compilation
         time for stylesheets where a single template declares 500 local variables. Should
         we have run tests to prevent that? Well, perhaps we should have more extreme cases
         in our test suite: the vast majority of our test cases are trivially small. But the
         problem is, there will always be users who do things that we would never have imagined.
         Like the user running an XSD 1.1 schema validation in which tens of thousands of assertions
         are expected to "fail", because they've written it in such a way that assertion failures
         aren't really errors, they are just a source of statistics for reporting on the data.
         </p>
      <p>
         The bugs we hate most (and therefore should to most to prevent) are bugs in bytecode
         generation, streaming, and multi-threading. The reason we hate them is that they can
         be a pig to debug, especially when the user-written application is large and complex. 
         </p>
      <p>
         
         
         
         <ul>
            <li>For bytecode generation I think we've actually got pretty good test coverage, because
               we not only run every test in the QT3 and XSLT3 test suites with bytecode generation
               enabled, we also artificially complicate the tests to stop queries like 2+5 being
               evaluated by the compiler before bytecode generation kicks in. We've also got an internal
               recovery mechanism so if we detect that we've generated bad code, we fall back to
               interpreted mode and the user never notices (problem with that is of course that we
               never find out).</li>
            <li>Streaming is tricky because the code is so convoluted (writing everything as inverted
               event-based code can be mind-blowing) and because the effects of getting it wrong
               often give very little clue as to the cause. But at least the failure is "in your
               face" for the user, who will therefore report the problem, and it's likely to be reproducible.
               Another difficulty with streaming is that because not all code is streamable, tests
               for streaming needed to be written from scratch.</li>
            <li>Multi-threading bugs are horrible because they occur unpredictably. If there's a low
               probability of the problem happening then it can require a great deal of detective
               work to isolate the circumstances, and this often falls on the user rather than on
               ourselves. Fortunately we only get a couple of these a year, but they are a nightmare
               when they come. In 9.7 we changed our Java baseline to Java 6 and were able therefore
               to replace many of the hand-built multithreading code in Saxon with standard Java
               libraries, which I think has helped reliability a lot. But there are essentially no
               tools or techniques to protect you from making simple thread-safety blunders, like
               setting a property in a shared object without synchronization. Could we do more testing
               to prevent these bugs? I'm not optimistic, because the bugs we get are so few, and
               so particular to a specific workload, that searching the haystack just in case it
               contains a needle is unlikely to be effective.</li>
         </ul>
         Summary: Having the product perceived as reliable by our users is more important to
         us than the actual bug count. Fixing bugs quickly before they affect more users is
         probably the best way of achieving that. If the bug count is high because we're raising
         bugs ourselves as a result of our own testing, then that's no bad thing. It hasn't
         yet got to the level where we can't cope with the volumes, or where we have to filter
         things through staff who are only employed to do support. If we can do things better,
         let us know.
         
         
         </p>
   </div></content></entry><entry><title>Guaranteed Streamability</title><link href="https://blog.saxonica.com/mike/2016/12/guaranteed-streamability.html" rel="alternate" type="text/html"/><id>https://blog.saxonica.com/mike/2016/12/guaranteed-streamability.html</id><published>2016-12-09T21:56:27Z</published><content type="xhtml" xml:base="https://blog.saxonica.com/mike/2016/12/guaranteed-streamability.html"><div xmlns="http://www.w3.org/1999/xhtml">
      
      <p>The XSLT 3.0 specification in its current form provides a set of rules (that can be
         evaluated statically, purely by inspecting the stylesheet) for determining whether
         the code is (or is not) guaranteed streamable.
         </p>
      <p>
         If the code is guaranteed streamable then every processor (if it claims to support
         streaming at all) must use streaming to evaluate the stylesheet; if it is not guaranteed
         streamable then the processor can choose whether to use streaming or not.
         </p>
      <p>
         The tricky bit is that there's a requirement in the spec that if the code isn't guaranteed
         streamable, then a streaming processor (on request) has to detect this and report
         it. The status section of the spec says that this requirement is "at risk", meaning
         it might be removed if it proves too difficult to implement. There are people on the
         working group who believe passionately that this requirement is really important for
         interoperability; there are others (including me) who fully understand why users would
         like to have this, but have been arguing that it is extremely difficult to deliver.
         </p>
      <p>
         In this article I'm going to try to explain why it's so difficult to achieve this
         requirement, and to explore possibilities for overcoming these difficulties.
         </p>
      <p>
         Streamability analysis can't be performed until various other stages of static analysis
         are complete. It generally requires that names have been resolved (for example, names
         of modes and names of streamable functions). It also relies on rudimentary type analysis
         (determining the static type of constructs). For Saxon, this means that streamability
         analysis is done after parsing, name fixup, type analysis, and rewrite optimization.
         </p>
      <p>
         When Saxon performs these various stages of analysis, it modifies the expression tree
         as it goes: not just to record the information obtained from the analysis, but to
         make use of the information at execution time. It goes without saying that in modifying
         the expression tree, it's not permitted to replace a streamable construct with a non-streamable
         one, and that isn't too hard to achieve (though these things are relative...). But
         the requirement to report departures from guaranteed streamability imposes a second
         requirement, which is proving much harder. If we are to report any deviations from
         guaranteed streamability, then up to the point where we do the streamability analysis,
         we must never replace a non-streamable construct with a streamable one.
         </p>
      <p>
         There are various points at which we currently replace a non-streamable construct
         with a streamable one.
         </p>
      <p>
         
         
         
         <ul>
            <li>Very early in the process, the expression tree that is output by the parsing phase
               uses the same data structure on the expression tree to represent equivalent constructs
               in the source. For example, the expression tree produced by &lt;xsl:if test="$a=2"&gt;&lt;xsl:sequence
               select="3"/&gt;&lt;/xsl:if&gt; will be identical to the expression tree produced by &lt;xsl:sequence
               select="if ($a=2) then 3 else ()"/&gt;. But streamability analysis makes a distinction
               between these two constructs. It's not a big distinction (in fact, the only thing
               it affects is exactly where you are allowed to call the accumulator-after() function)
               but it's big enough to count.</li>
            <li>At any stage in the process, if we spot a constant expression then we're likely to
               replace it with its value. For example if we see the expression $v+3, and $v is a
               global variable whose value is 5, we will replace the expression with the literal
               8. This won't usually affect streamability one way or the other. However, there are
               a few cases where it does. The most obvious is where we work out that an expression
               is void (meaning it always returns an empty sequence). For example, according to the
               spec, the expression (author[0], author[1]) is not streamable because it makes two
               downward selections. But Saxon spots that author[0] is void and rewrites the expression
               as (author[1]), which is streamable. Void expressions often imply some kind of user
               error, so we often output a warning when this happens, but just because we think the
               user has written nonsense doesn't absolve us from the conformance requirement to report
               on guaranteed streamability. Void expressions are particularly likely to be found
               with schema-aware analysis.</li>
            <li>Inlining of calls to user-defined functions will often make a non-streamable expression
               streamable.</li>
            <li>Many other rewrites performed by the optimizer have a similar effect, for example
               replacing (X|Y) by *[self::X|self::Y].</li>
         </ul>
         My first attempt to meet the requirement is therefore (a) to add information to the
         expression tree where it's needed to maintain a distinction that affects streamability,
         and (b) to try to avoid those rewrites that turn non-streamable expressions into streamable
         ones. As a first cut, skipping the optimization phase completely seems an easy way
         to achieve (b). But it turns out it's not sufficient, firstly because some rewrites
         are done during the type-checking phase, and secondly because it turns out that without
         an optimization pass, we actually end up finding that some expressions that should
         be streamable are not. The most common case for this is sorting into document order.
         Given the expression A/B, Saxon actually builds an expression in the form sort(A!B)
         relying on the sort operation to sort nodes into document order and eliminate duplicates.
         This relies on the subsequent optimization phase to eliminate the sort() operation
         when it can. If we skip the optimization phase, we are left with an unstreamable expression.
         
         </p>
      <p>
         The other issue is that the streamability rules rely on type inferencing rules that
         are much simpler than the rules Saxon uses. It's only in rare cases that this will
         make a difference, of course: in fact, it requires considerable ingenuity to come
         up with such cases. The most obvious case where types make a difference to streamability
         is with a construct like &lt;xsl:value-of select="$v"/&gt;: this is motionless if $v is
         a text or attribute node, but consuming if it is a document or element node. If a
         global variable with private visibility is initialized with select="@price", but has
         no "as" attribute, Saxon will infer a type of attribute(price) for the variable, but
         the rules in the spec will infer a type of item()*. So to get the same streamability
         answer as the spec gives, we need to downgrade the static type inferencing in Saxon.
         </p>
      <p>
         So I think the changes needed to replicate exactly the streamability rules of the
         XSLT 3.0 spec are fairly disruptive; moreover, implementing the changes by searching
         for all the cases that need to change is going to be very difficult to get right (and
         is very difficult to test unless there is another trustworthy implementation of the
         rules to test against).
         </p>
      <p>
         This brings us to Plan B. Plan B is to meet the requirement by writing a completely
         free-standing tool for streamability analysis that's completely separate from the
         current static analysis code. One way to do this would be to build on the tool written
         by John Lumley and demonstrated at Balisage a couple of years ago. Unfortunately that's
         incomplete and out of date, so it would be a significant effort to finish it. Meeting
         the requirement in the spec is different here from doing something useful for users:
         what the spec demands is a yes/no answer as to whether the code is streamable; what
         users want to know is why, and what they need to change to make the code streamable.
         The challenge is to do this without users having to understand the difficult abstractions
         in the spec (posture, sweep, and the rest). John's tool produces an annotated expression
         tree revealing all the properties: that's great for a user who understands the methodology
         but probably rather bewildering to the typical end user. Doing the minimum for conformance,
         a tool that just says yes or no without saying why, involves a lot of work to get
         a "tick in the box" with a piece of software that no-one will ever use, but would
         be a lot easier to produce. Conformance has always been a very high priority for Saxonica,
         but I can't see anyone being happy with this particular solution.
         </p>
      <p>
         So, assuming the WG maintains its insistence of having this feature (and it seems
         to me likely that it will), what should we do about it?
         </p>
      <p>
         One option is simply to declare a non-conformance. Once upon a time, standards conformance
         was very important to Saxon's reputation in the market, but I doubt that this particular
         non-conformance would affect our sales.
         </p>
      <p>
         Another option is to declare conformance, do our best to achieve it using the current
         analysis technology, and simply log bugs if anyone reports use cases where we get
         the answer wrong. That seems sloppy and dishonest, and could leave us with a continuing
         stream of bugs to be fixed or ignored.
         </p>
      <p>
         Another option is the "minimal Plan B" analyser - a separate tool for streamability
         analysis, that simply reports a yes/no answer (without explanation). It would be significant
         piece of work to create this and test it, and it's unclear that anyone would use it,
         but it's probably the cheapest way of getting the conformance tick-in-the-box.
         </p>
      <p>
         A final option is to go for a "fully featured" but free-standing streamability analysis
         tool, one which aims to not only answer the conformance question about guaranteed
         streamability, but also to provide genuinely useful feedback and advice helping users
         to create streamable stylesheets. Of course ideally such a tool would be integrated
         into an IDE rather than being free-standing. I've always argued that there's only
         a need for one such tool: it's not something that every XSLT 3.0 processor needs to
         provide. Doing this well would be a large project and involves different skills from
         those we currently have available.
         </p>
      <p>
         In the short term, I think the only honest and affordable approach would be the first
         option: declare a non-conformance. Unfortunately that could threaten the viability
         of the spec, because we can only get a spec to Recommendation status if all features
         have been shown to be implementable.
         </p>
      <p>
         No easy answers.
         </p>
      <p>
         <b>LATER</b></p>
      <p>
         I've been thinking about a Plan C which might fly...
         </p>
      <p>
         The idea here is to try and do the streamability analysis using the current expression
         tree structure and the current streamability logic, but applying the streamability
         rules to an expression tree that faithfully represents the stylesheet as parsed, with
         no modifications from type checking or optimization.
         </p>
      <p>
         To do this, we need to:
         </p>
      <ul>
         <li>Define a configuration flag --strictStreamability which invokes the following logic.</li>
         <li>Fix places where the initial expression tree loses information that's needed for
            streamability analysis. The two that come to mind are (a) losing the information that
            something is an instruction rather than an expression (e.g. we lose the distinction
            between xsl:map-entry and a singleton map expression) - this distinction is needed
            to assess calls on accumulator-after(); (b) turning path expressions A/B into docSort(A!B).
            There may be other cases that we will discover along the road (or fail to discover,
            since we may not have a complete set of test cases...)</li>
         <li>Write a new type checker that attaches type information to this tree according to
            the rules in the XSLT 3.0 spec. This will be much simpler than the existing type checker,
            partly because the rules are much simpler, but more particularly because the only
            thing it will do is to assign static types: it will never report any type errors,
            and it will never inject any code to do run-time type checking or conversion.</li>
         <li>Immediately after this type-checking phase, run the existing streamability rules
            against the expression tree. As far as I'm aware, the streamability rules in Saxon
            are equivalent to the W3C rules (at any rate, most of the original differences have
            now been eliminated).</li>
      </ul>
      <p>
         There are then two options. We could stop here: if the user sets the --strictStreamability
         flag, they get the report on streamability, but they don't get an executable that
         can actually be run. The alternative would be, if the streamability analysis succeeds,
         attempt to convert the expression tree into a form that we can actually use, by running
         the existing simplify / typecheck / optimize phases. The distinctions introduced to
         the expression tree by the changes described above would be eliminated by the simplify()
         phase, and we would then proceed along the current lines, probably including a rerun
         of the streamability analysis against the optimised expression tree (because the posture+sweep
         annotations are occasionally needed at run-time).
         </p>
      <p>
         I will do some further exploration to see whether this all looks feasible. It will
         be very hard to prove that we've got it 100% right. But in a sense that doesn't matter,
         so long as the design is sound and we're passing known tests then we can report honestly
         that to the best of our knowledge the requirement is satisfied, which is not the case
         with the current approach.
         </p>
   </div></content></entry></feed>