Project

Profile

Help

Bug #5230

closed

Difficulty using xsl:xpath-default-namespace in conjunction with the key attribute of xsl:map-entry

Added by Matthew Boyd 4 months ago. Updated 4 days ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Category:
XSLT Conformance
Sprint/Milestone:
-
Start date:
2022-01-25
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

Using saxon-js and given this input:

<foo:root xmlns:foo='http://www.example.com'>
      <foo:bar>Hello world</foo:bar>
</foo:root>

And this stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xpath-default-namespace="http://www.example.com">

  <xsl:output method="json"/>

  <xsl:template match="/">
    <xsl:map-entry key="'greeting'" select="string(//bar)"/>
  </xsl:template>

</xsl:stylesheet>

I get this output:

{"greeting": "Hello world"}

However, if I attempt to use the same Xpath to select the key instead of the value, as such:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xpath-default-namespace="http://www.example.com">

  <xsl:output method="json"/>

  <xsl:template match="/">
    <xsl:map-entry key="string(//bar)" select="'greeting'"/>
  </xsl:template>

</xsl:stylesheet>

I get an empty string for the key:

{"": "greeting"}

Attempting this same transformation with the saxon processor bundled with oXygen (v 9.9.1.7 at time of writing) produces the output I expect, however:

{"Hello world":"greeting"}
Actions #1

Updated by Martin Honnen 4 months ago

Interesting, using <xsl:map-entry key="data(//bar)" select="'greeting'"/> instead of <xsl:map-entry key="string(//bar)" select="'greeting'"/> gives the error Cannot read property 'hashCode' of null with Node.js or Cannot read properties of null (reading 'hashCode') in the browser.

As you mention you also use oXygen, have you tried to use Saxon 9.9.1.7 to compile/export an SEF for Saxon-JS and then check whether Saxon-JS doesn't produce the error?

Actions #2

Updated by Michael Kay 4 months ago

I have put this into a new XSLT3 test maps/maps-017.

Confirmed that it fails under node.js as described.

Looking at the SEF file, if we use //bar in the select attribute, it compiles as

{
     "N": "axis",
      "name": "descendant",
      "nodeTest": "*NE nQ{http://www.example.com}bar"
 }

whereas in the key attribute it compiles as

{
     "N": "axis",
      "name": "descendant",
      "nodeTest": "*NE nQ{}bar"
 }

So the bug is in the XX compiler.

Actions #3

Updated by Michael Kay 4 months ago

I suspect that in maps.xsl line 32

<xpath role="key" xpath="data({@key})" line="{f:line-number(.)}"/>

should be

<xsl:apply-templates select="@key" mode="create.xpath"/>

except I'm not sure how we achieve the atomisation: perhaps with a $type or $checkType parameter? This invokes the template rule in XSLT-SEF-compiler.xsl line 1819, which picks up the tunnel parameter xpath-default-namespace.

There are other places that appear to generate an <xpath> instruction directly without taking account of xpath-default-namespace, these include

  • xsl:key/@use (key.xsl line 29)
  • xsl:for-each-group/@group-by (grouping.xsl line 73) (But @group-adjacent on line 88 handles the xpath-default-namespace directly, perhaps we could follow that example - it's also used for xsl:number/@value in numbering.xsl line 32))
  • ixsl:set-attribute, remove-attribute etc = ixsl.xsl lines 22, 35, 36, 49, 62, 76, etc
Actions #4

Updated by Michael Kay 4 months ago

Note also, if we do use "data({@key})" to achieve atomisation, it should be "data(({@key}))" to allow for something like key="$x, $y".

Actions #5

Updated by Michael Kay 4 months ago

I also added tests key/key-099 to test for default namespace in xsl:key/@use -- which fails, and for-each-group/for-each-group-091 - which succeeds.

Actions #6

Updated by Michael Kay 3 months ago

  • Status changed from New to In Progress

(Current status: patch developed but not fully tested, therefore not committed.)

Actions #7

Updated by Michael Kay 3 months ago

As suggested in comment #3, there was indeed a problem with atomisation (leading to the error $key$$.hashCode is not a function).

The atomization can be forced by changing the apply-templates call to

            <data>
                <xsl:apply-templates select="@key" mode="create.xpath"/>  
            </data>
Actions #8

Updated by Michael Kay 3 months ago

  • Status changed from In Progress to Resolved
  • Applies to JS Branch 2 added
  • Fix Committed on JS Branch Trunk added
Actions #9

Updated by Michael Kay about 2 months ago

  • Status changed from Resolved to In Progress

Reopening as test key-099 is still failing (with both compilers).

Actions #10

Updated by Michael Kay about 2 months ago

Looking at the SEF file produced for key-099, (a) for the XX compiler, the "use" attribute of xsl:key seems to lack the default namespace, but (b) for the XJ compiler, it looks fine.

I've changed the XX compiler at key.xsl#32 in the same way as comment #7, and the test is now working.

But the XJ-compiled test still fails...

Running the test transformation outside the test driver works, however, so I think I've got a problem with my configuration for running the test driver.

Actions #11

Updated by Michael Kay about 2 months ago

  • Status changed from In Progress to Resolved

Fixed my test driver issues; test key-099 is now working with both compilers.

Actions #12

Updated by Debbie Lockett about 1 month ago

  • Fix Committed on JS Branch 2 added
  • Fix Committed on JS Branch deleted (Trunk)
Actions #13

Updated by Debbie Lockett 4 days ago

  • Status changed from Resolved to Closed
  • % Done changed from 0 to 100
  • Fixed in JS Release set to SaxonJS 2.4

Bug fix applied in the SaxonJS 2.4 maintenance release.

Please register to edit this issue

Also available in: Atom PDF Tracking page