Project

Profile

Help

Bug #4690

closed

generate-id problem when chaining stylesheets and storing intermediary results as a tree

Added by Martin Honnen over 3 years ago. Updated about 3 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
-
Sprint/Milestone:
-
Start date:
2020-08-21
Due date:
% Done:

100%

Estimated time:
Applies to JS Branch:
2
Fix Committed on JS Branch:
2
Fixed in JS Release:
SEF Generated with:
Platforms:
Company:
-
Contact person:
-
Additional contact persons:
-

Description

While trying to run Schematron with Saxon-JS 2 instead of Saxon Java I have run into an odd problem: the schematron compilation consists of three XSLT steps to convert a Schematron schema to an XSLT stylesheet; when I run these steps with Saxon-JS 2 SaxonJS.transform using a tree as the intermediary result format the third step doing the compilation fails with an error by Saxon-JS that a required parameter has not been supplied.

On inspecting the stylesheet it seems the parameter is passed on using generate-id() but somehow that doesn't bind a value in the receiving template.

This only happens when I use a tree as the intermediary result, if I serialize intermediary results the problem doesn't occur.

I have managed to reduce the problem to a two step process where the first does an identity spelled out as a template:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="2.0">
    
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
    
</xsl:stylesheet>

and the second XSLT tries to pass on a generate-id() inside of for-each-group:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">
    
    <xsl:mode on-no-match="shallow-copy"/>
    
    <xsl:template match="/*">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:for-each-group select="item" group-by=".">
                <xsl:apply-templates select=".">
                    <xsl:with-param name="id" as="xs:string" select="generate-id()"/>
                </xsl:apply-templates>
            </xsl:for-each-group>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="item">
        <xsl:param name="id" as="xs:string" required="yes"/>
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:attribute name="generated-id" select="$id"/>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>
    
</xsl:stylesheet>

When I run the two stylesheets with Node.js using code

require('saxon-js');

const step1Result = SaxonJS.transform({
    stylesheetFileName : 'identity-2.sef.json',
    sourceFileName : 'sample1.xml'
});

const step2Result = SaxonJS.transform({
    stylesheetFileName : 'generate-id-test2.sef.json',
    sourceNode : step1Result.principalResult,
    destination : 'serialized'
});

console.log(step2Result.principalResult);

I get an error

  message: 'Required parameter $Q{}id not supplied',
  code: 'XTDE0700',
  xsltLineNr: '21',
  xsltModule: 'generate-id-test2.xsl',

A sample input would be

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <item>a</item>
    <item>b</item>
</root>

If I run the second stylesheet alone all works fine, somehow the first step, although doing nothing but an identity transformation, causes the problem with the binding of generate-id() in the second step.

The used sef.json files were simply generated using xslt3 from above shown XSLT stylesheets.

Please register to edit this issue

Also available in: Atom PDF Tracking page