1

I am trying to transform XML using stylesheets that reference other xsl stylesheets. I compile the main stylesheet using xslt3 on the command line into a .sef.json file, but when I use that .sef.json with .transform(), I get a Failed URI resolution error.

I call transform as follows:

SaxonJS.transform({
            stylesheetInternal: splXslJS,
            sourceText: input,
            destination: 'serialized'
        }, "async")

fhirXslJS is compiled from this XSL:

<?xml version="1.0" encoding="us-ascii"?>
<!--
The contents of this file are subject to the Health Level-7 Public
License Version 1.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of the
License at http://www.hl7.org/HPL/hpl.txt.

Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and
limitations under the License.

The Original Code is all this file.

The Initial Developer of the Original Code is Gunther Schadow.
Portions created by Initial Developer are Copyright (C) 2002-2004
Health Level Seven, Inc. All Rights Reserved.

Contributor(s): Steven Gitterman, Brian Keller

Revision: $Id: spl.xsl,v 1.52 2005/08/26 05:59:26 gschadow Exp $

Revision: $Id: spl-common.xsl,v 2.0 2006/08/18 04:11:00 sbsuggs Exp $

-->
<xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:v3="urn:hl7-org:v3" exclude-result-prefixes="v3 xsl">
    <xsl:import href="./spl-common.xsl"/>
    <!-- Where to find JavaScript resources -->
    <xsl:param name="resourcesdir">http://www.accessdata.fda.gov/spl/stylesheet/</xsl:param>
    <!-- Whether to show the clickable XML, set to "/.." instead of "1" to turn off -->
    <xsl:param name="show-subjects-xml" select="/.."/>
    <!-- Whether to show the data elements in special tables etc., set to "/.." instead of "1" to turn off -->
    <xsl:param name="show-data" select="1"/>
    <!-- This is the CSS link put into the output -->
    <xsl:param name="css">http://www.accessdata.fda.gov/spl/stylesheet/spl.css</xsl:param>
    <!-- Whether to show section numbers, set to 1 to enable and "/.." to turn off-->
    <xsl:param name="show-section-numbers" select="/.."/>
    <!-- Whether to process mixins -->
    <xsl:param name="process-mixins" select="true()"/>
    <xsl:param name="core-base-url">http://www.accessdata.fda.gov/spl/core</xsl:param>
    <xsl:output method="html" version="5.0" encoding="UTF-8" indent="yes"/>
    <xsl:strip-space elements="*"/>
</xsl:transform>

The line causing the error is this <xsl:param name="indexingDocumentTypes" select="document('indexing-doc-types.xml')/*"/> in referenced spl-common.xsl:

<?xml version="1.0" encoding="us-ascii"?>
<!--
The contents of this file are subject to the Health Level-7 Public
License Version 1.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of the
License at http://www.hl7.org/HPL/hpl.txt.

Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and
limitations under the License.

The Original Code is all this file.

The Initial Developer of the Original Code is Gunther Schadow.
Portions created by Initial Developer are Copyright (C) 2002-2013
Health Level Seven, Inc. All Rights Reserved.

Contributor(s): Steven Gitterman, Brian Keller, Brian Suggs

TODO: footnote styleCode Footnote, Endnote not yet obeyed
TODO: Implementation guide needs to define linkHtml styleCodes.
-->
<xsl:transform version="2.0" 
                             xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                             xmlns:v3="urn:hl7-org:v3" 
                             xmlns:v="http://validator.pragmaticdata.com/result" 
                             xmlns:str="http://exslt.org/strings" 
                             xmlns:exsl="http://exslt.org/common" 
                             xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
                             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                             exclude-result-prefixes="exsl msxsl v3 xsl xsi str v">
    <xsl:import href="xml-verbatim.xsl"/>
    <xsl:import href="mixin.xsl"/>
    <xsl:import href="substance.xsl"/>
    <xsl:import href="pesticide.xsl"/>
    <xsl:param name="show-subjects-xml" select="1"/>
    <xsl:param name="show-data" select="/.."/>
    <xsl:param name="show-section-numbers" select="/.."/>
    <xsl:param name="update-check-url-base" select="/.."/>
    <xsl:param name="standardSections" select="document('plr-sections.xml')/*"/>
    <xsl:param name="itemCodeSystems" select="document('item-code-systems.xml')/*"/>
    <xsl:param name="disclaimers" select="document('disclaimers.xml')/*"/>
    <xsl:param name="documentTypes" select="document('doc-types.xml')/*"/>
    <xsl:param name="indexingDocumentTypes" select="document('indexing-doc-types.xml')/*"/>
    <xsl:param name="root" select="/"/>
    <xsl:param name="css" select="'./spl.css'"/>
    <xsl:param name="process-mixins" select="/.."/>
    <xsl:output method="html" version="5.0" encoding="UTF-8" indent="no" doctype-public="-"/>
    <xsl:strip-space elements="*"/>
    <!-- The indication secction variable contains the actual Indication Section node-->
    <xsl:variable name="indicationSection" select="/v3:document/v3:component/v3:structuredBody/v3:component//v3:section [v3:code [descendant-or-self::* [(self::v3:code or self::v3:translation) and @codeSystem='2.16.840.1.113883.6.1' and @code='34067-9'] ] ]"/>
    <xsl:variable name="indicationSectionCode">34067-9</xsl:variable>
    <xsl:variable name="dosageAndAdministrationSectionCode">34068-7</xsl:variable>
    <xsl:variable name="timeUnitsList">
        <unitsMapping>
            <unit UCUM="s" singular="second" plural="seconds"/>
            <unit UCUM="min" singular="minute" plural="minutes"/>
            <unit UCUM="h" singular="hour" plural="hours"/>
            <unit UCUM="d" singular="day" plural="days"/>
            <unit UCUM="wk" singular="week" plural="weeks"/>
            <unit UCUM="mo" singular="month" plural="months"/>
            <unit UCUM="a" singular="year" plural="years"/>
        </unitsMapping>
    </xsl:variable>

(much more in this file but don't think it's necessary)

This is the error I'm getting: XError:Failed URI resolution: href=./indexing-doc-types.xml base=file:///C:/Users/7J2197897/Desktop/FDA/SPL-FHIR-Demo/spl-fhir-demo/src/assets/HTML-View-Xform-SPL/spl-common.xsl -- TypeError: r is not a constructor; code:FODC0005

Other potentially relevant context:

  • This is from a React app running on Firefox
  • Node module "saxon-js": "^2.4.0",
  • Compiled spl.xsl with xslt3 -xsl:spl.xsl -export:spl.sef.json --t --nogo --ns:##html5
  • sourceText is an XML string the user inputs
  • I have also tried compiling with relocate:on and passing stylesheetBaseURI but that didn't work

Appreciate any help!

anna.go
  • 23
  • 2
  • Are you using browser version of SaxonJS to run the stylesheet in the browser? Have you seen the section about preloading resources e.g. https://www.saxonica.com/saxon-js/documentation2/index.html#!development/source-documents and https://www.saxonica.com/saxon-js/documentation2/index.html#!api/getResource? Anyway, does `document()` fail for that particular document or for all of them? What happens if you set `relocate:on` during compilation, which error do you get then at runtime? – Martin Honnen Sep 07 '22 at 05:38
  • Also, have you run a stylesheet previously that you work with e.g. `stylesheetInternal: splXslJS`? Or should you rather use `stylesheetText` or `stylesheetLocation`? – Martin Honnen Sep 07 '22 at 05:53
  • Yes, it seems like document() is only failing for that particular document. I've tried preloading that xml but SaxonJS.getResource() gives me an error `TypeError: D.promises is undefined`, traceback is ```resourcePromise SaxonJS2N.js:191877 getResource SaxonJS2N.js:201840 goToSPLHTML SPLToFHIR.js:146``` . Using stylesheetText, stylesheetLocation, and relocate:on all give the same URI resolution failed error. – anna.go Sep 07 '22 at 17:29
  • I also tried pre-fetching the resource using getResource() with the intent to pass the result in documentPool (of transform()) but getResource() failed saying `D.promises` is undefined. – anna.go Sep 08 '22 at 14:33
  • The best way forward is probably trying to get Norm/Saxonica something that allows them to reproduce that bug. – Martin Honnen Sep 08 '22 at 17:14
  • I also tried running it through the command line and this generated the expected output: `xslt3 -s:SPL-NDC-Labeler-Code-Request-01.xml -xsl:../../assets/HTML-View-Xform-SPL/spl.xsl -o:thisworks.html -t` -- do you have any insight as to why the command works but the Node version does not? – anna.go Sep 08 '22 at 19:47
  • As far as I understand, `xslt3` is just the command line interface to SaxonJS under Node, i.e. it uses that Node.js saxon-js module as well. I am afraid I can't tell what using the module "saxon-js": "^2.4.0" in a React app running on Firefox really all involves and what can go wrong there, I am sure Norm/Saxonica will try to investigate. – Martin Honnen Sep 08 '22 at 20:10

1 Answers1

0

That's interesting. It certainly doesn't look like that URI resolution should fail. (The fact that you get a weird message about r is not a constructor is certainly a SaxonJS bug: thank you!)

You said it "didn't work" when you tried it with relocation enabled, did it fail in exactly the same way?

I'm not personally familiar with exactly how React bundles a Node.JS version of a module into the browser (is that what it's doing!?). If it's practical for you to try loading the browser version of SaxonJS instead of the Node.js package, that might shed light on the situation.

I appreciate that this going to be a big ask, but if you can narrow this down to a small test case that I can reproduce, that will make it a lot easier to pin down.

Norm
  • 866
  • 1
  • 7
  • 16
  • It failed in the same way, the error message would change `base=` to be whatever I set the `stylesheetBaseURI` to, which makes sense. I'm also not sure how React interacts with the SaxonJS Node module, how is the browser version different and how would I access it? I'll attempt to narrow this issue down to a test case but there are so many dependencies I'm not sure I'll be able to, I'm sorry! – anna.go Sep 07 '22 at 17:31
  • We compile the source into a browser version and a Node.js version. They're very similar platforms, but there are differences around the edges. You can access the browser version by downloading it from our website, installing it locally, and then loading it into the browser. (I'd like to package it up as an NPM too, but I haven't yet worked out how to get the Closure compiler to produce artifacts that will work that way.) – Norm Sep 09 '22 at 08:57