Home > Net >  Node xslt-processor does not transform my XML
Node xslt-processor does not transform my XML

Time:09-01

I am trying to transform an XML input using an XSLT file but it's only outputting the root tags. I am using the node module xslt-processor to keep it browser-agnostic.

When I test with a small example, the transformation works as expected.

The XML and XSLT files I'm working with are below, and this is the output:

<Bundle xmlns="http://hl7.org/fhir" xmlns:xhtml="http://www.w3.org/1999/xhtml"/>

XML:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="https://www.accessdata.fda.gov/spl/stylesheet/spl.xsl" type="text/xsl"?>
<document xmlns="urn:hl7-org:v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:hl7-org:v3 https://www.accessdata.fda.gov/spl/schema/spl.xsd">
  <id root="fadc3edf-d17c-42a0-8e3a-1a1d6eaf07a4"/>
  <code code="51726-8" codeSystem="2.16.840.1.113883.6.1" displayName="NDC/NHRIC LABELER CODE REQUEST"/>
  <effectiveTime value="20220120"/>
  <setId root="f3ee38c6-4523-4fff-86fb-8d14de6652c4"/>
  <versionNumber value="2"/>
  <author>
    <time/>
    <assignedEntity>
      <representedOrganization>
        <id root="1.3.6.1.4.1.519.1" extension="245621042"/>
        <id root="2.16.840.1.113883.6.69" extension="15365"/>
        <name>National Pharma of Australia Inc.</name>
        <contactParty>
          <addr>
            <country>AUS</country>
            <state>Telangana</state>
            <city>RangareddyDistrict</city>
            <postalCode>500001</postalCode>
            <streetAddressLine>Plot 101 First Street</streetAddressLine>
          </addr>
          <telecom value="tel: 9-140-111-2222"/>
          <telecom value="mailto:[email protected]"/>
          <contactPerson>
            <name>Mr. John Doe_1</name>
          </contactPerson>
        </contactParty>
        <assignedEntity>
          <assignedOrganization>
            <assignedEntity>
              <assignedOrganization>
                <id root="1.3.6.1.4.1.519.1" extension="245621042"/>
                <name>National Pharma of Australia Inc.</name>
                <addr>
                  <country>AUS</country>
                  <state>Telangana</state>
                  <city>RangareddyDistrict</city>
                  <postalCode>500002</postalCode>
                  <streetAddressLine>Plot 102 Village Ave</streetAddressLine>
                </addr>
                <assignedEntity>
                  <assignedOrganization>
                    <id root="1.3.6.1.4.1.519.1" extension="398988034"/>
                    <name>New National Pharma of Australia Inc. US Agent</name>
                    <telecom value="tel: 1-908-999-1213"/>
                    <telecom value="mailto:[email protected]"/>
                  </assignedOrganization>
                  <performance>
                    <actDefinition>
                      <code code="C73330" codeSystem="2.16.840.1.113883.3.26.1.1" displayName="united states agent"/>
                    </actDefinition>
                  </performance>
                </assignedEntity>
              </assignedOrganization>
              <performance>
                <actDefinition>
                  <code code="C43360" codeSystem="2.16.840.1.113883.3.26.1.1" displayName="manufacture"/>
                  <subjectOf>
                    <approval>
                      <code code="C106643" codeSystem="2.16.840.1.113883.3.26.1.1" displayName="Manufactures human prescription drug products"/>
                    </approval>
                  </subjectOf>
                </actDefinition>
              </performance>
            </assignedEntity>
          </assignedOrganization>
        </assignedEntity>
      </representedOrganization>
    </assignedEntity>
  </author>
  <component>
    <structuredBody/>
  </component>
</document>

XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<!--
This file was generated by Altova MapForce 2021r3

YOU SHOULD NOT MODIFY THIS FILE, BECAUSE IT WILL BE
OVERWRITTEN WHEN YOU RE-RUN CODE GENERATION.

Refer to the Altova MapForce Documentation for further details.
http://www.altova.com/mapforce
-->
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tbf="http://www.altova.com/MapForce/UDF/tbf" xmlns:user="http://www.altova.com/MapForce/UDF/user" xmlns:vmf="http://www.altova.com/MapForce/UDF/vmf" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:ns0="urn:hl7-org:v3" exclude-result-prefixes="tbf user vmf xs fn ns0">
    <xsl:template name="tbf:tbf2_Simple-CD">
        <xsl:param name="input" select="()"/>
        <xsl:for-each select="$input/@code">
            <xsl:attribute name="code" select="fn:string(.)"/>
        </xsl:for-each>
        <xsl:for-each select="$input/@codeSystem">
            <xsl:attribute name="codeSystem" select="fn:string(.)"/>
        </xsl:for-each>
        <xsl:for-each select="$input/@displayName">
            <xsl:attribute name="displayName" select="fn:string(.)"/>
        </xsl:for-each>
    </xsl:template>
    <xsl:template name="user:createOrganizationAffiliation">
        <xsl:param name="participatingId" select="()"/>
        <xsl:param name="SimpleCD" select="()"/>
        <OrganizationAffiliation xmlns="http://hl7.org/fhir">
            <organization>
                <reference>
                    <xsl:attribute name="value" namespace="" select="'#'"/>
                </reference>
            </organization>
            <participatingOrganization>
                <reference>
                    <xsl:attribute name="value" namespace="" select="$participatingId"/>
                </reference>
            </participatingOrganization>
            <code>
                <coding>
                    <system>
                        <xsl:attribute name="value" namespace="" select="xs:string(xs:anyURI('http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl'))"/>
                    </system>
                    <code>
                        <xsl:for-each select="$SimpleCD/@code">
                            <xsl:attribute name="value" namespace="" select="fn:string(.)"/>
                        </xsl:for-each>
                    </code>
                    <display>
                        <xsl:for-each select="$SimpleCD/@displayName">
                            <xsl:attribute name="value" namespace="" select="fn:string(.)"/>
                        </xsl:for-each>
                    </display>
                </coding>
            </code>
        </OrganizationAffiliation>
    </xsl:template>
    <xsl:template name="user:parseTelecom">
        <xsl:param name="SimpleTEL" select="()"/>
        <xsl:variable name="var3_value" as="node()?" select="$SimpleTEL/@value"/>
        <ContactPoint xmlns="http://hl7.org/fhir">
            <system>
                <xsl:for-each select="$var3_value">
                    <xsl:attribute name="value" namespace="">
                        <xsl:call-template name="vmf:vmf8_inputtoresult">
                            <xsl:with-param name="input" select="fn:substring-before(xs:string(xs:anyURI(fn:string(.))), ':')" as="xs:string"/>
                        </xsl:call-template>
                    </xsl:attribute>
                </xsl:for-each>
            </system>
            <value>
                <xsl:for-each select="$var3_value">
                    <xsl:variable name="var2_cur_as_string" as="xs:string" select="xs:string(xs:anyURI(fn:string(.)))"/>
                    <xsl:variable name="var1_resultof_vmf__inputtoresult" as="xs:string">
                        <xsl:call-template name="vmf:vmf8_inputtoresult">
                            <xsl:with-param name="input" select="fn:substring-before($var2_cur_as_string, ':')" as="xs:string"/>
                        </xsl:call-template>
                    </xsl:variable>
                    <xsl:attribute name="value" namespace="">
                        <xsl:choose>
                            <xsl:when test="($var1_resultof_vmf__inputtoresult = 'url')">
                                <xsl:sequence select="$var2_cur_as_string"/>
                            </xsl:when>
                            <xsl:otherwise>
                                <xsl:sequence select="fn:substring-after($var2_cur_as_string, ':')"/>
                            </xsl:otherwise>
                        </xsl:choose>
                    </xsl:attribute>
                </xsl:for-each>
            </value>
        </ContactPoint>
    </xsl:template>
    <xsl:template name="user:createLabelerOrganization">
        <xsl:param name="LabelerOrganization" select="()"/>
        <xsl:variable name="var6_assignedEntity" as="node()*" select="$LabelerOrganization/ns0:assignedEntity"/>
        <xsl:variable name="var7_http___hl__org_fhir_us_spl_Cod_as_string" as="xs:string" select="xs:string(xs:anyURI('http://hl7.org/fhir/us/spl/CodeSystem/codesystem-organizationTypes'))"/>
        <Organization xmlns="http://hl7.org/fhir">
            <xsl:for-each select="$var6_assignedEntity/ns0:assignedOrganization/ns0:assignedEntity/ns0:performance">
                <xsl:variable name="var1_actDefinition" as="node()*" select="ns0:actDefinition"/>
                <contained>
                    <HealthcareService>
                        <providedBy>
                            <reference>
                                <xsl:attribute name="value" namespace="" select="'#'"/>
                            </reference>
                        </providedBy>
                        <xsl:for-each select="$var1_actDefinition/ns0:code">
                            <type>
                                <coding>
                                    <system>
                                        <xsl:attribute name="value" namespace="" select="xs:string(xs:anyURI('http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl'))"/>
                                    </system>
                                    <code>
                                        <xsl:for-each select="@code">
                                            <xsl:attribute name="value" namespace="" select="fn:string(.)"/>
                                        </xsl:for-each>
                                    </code>
                                    <display>
                                        <xsl:for-each select="@displayName">
                                            <xsl:attribute name="value" namespace="" select="fn:string(.)"/>
                                        </xsl:for-each>
                                    </display>
                                </coding>
                            </type>
                        </xsl:for-each>
                        <xsl:for-each select="$var1_actDefinition/ns0:subjectOf">
                            <serviceProvisionCode>
                                <xsl:for-each select="ns0:approval/ns0:code">
                                    <coding>
                                        <system>
                                            <xsl:attribute name="value" namespace="" select="xs:string(xs:anyURI('http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl'))"/>
                                        </system>
                                        <code>
                                            <xsl:for-each select="@code">
                                                <xsl:attribute name="value" namespace="" select="fn:string(.)"/>
                                            </xsl:for-each>
                                        </code>
                                        <display>
                                            <xsl:for-each select="@displayName">
                                                <xsl:attribute name="value" namespace="" select="fn:string(.)"/>
                                            </xsl:for-each>
                                        </display>
                                    </coding>
                                </xsl:for-each>
                            </serviceProvisionCode>
                        </xsl:for-each>
                    </HealthcareService>
                </contained>
            </xsl:for-each>
            <xsl:for-each select="$var6_assignedEntity/ns0:assignedOrganization/ns0:assignedEntity/ns0:assignedOrganization/ns0:assignedEntity">
                <xsl:variable name="var3_cur" as="node()" select="."/>
                <xsl:for-each select="ns0:assignedOrganization">
                    <contained>
                        <xsl:for-each select="$var3_cur/ns0:performance/ns0:actDefinition/ns0:code">
                            <xsl:variable name="var2_resultof_createOrganizationAffiliation" as="node()?">
                                <xsl:call-template name="user:createOrganizationAffiliation">
                                    <xsl:with-param name="participatingId" select="'#usagent'" as="xs:string"/>
                                    <xsl:with-param name="SimpleCD" as="node()">
                                        <Simple-CD xmlns="urn:hl7-org:v3">
                                            <xsl:call-template name="tbf:tbf2_Simple-CD">
                                                <xsl:with-param name="input" select="." as="node()"/>
                                            </xsl:call-template>
                                        </Simple-CD>
                                    </xsl:with-param>
                                </xsl:call-template>
                            </xsl:variable>
                            <xsl:for-each select="$var2_resultof_createOrganizationAffiliation">
                                <OrganizationAffiliation>
                                    <xsl:sequence select="(./@node(), ./node())"/>
                                </OrganizationAffiliation>
                            </xsl:for-each>
                        </xsl:for-each>
                    </contained>
                </xsl:for-each>
            </xsl:for-each>
            <xsl:for-each select="$var6_assignedEntity/ns0:assignedOrganization/ns0:assignedEntity/ns0:assignedOrganization/ns0:assignedEntity/ns0:assignedOrganization">
                <contained>
                    <Organization>
                        <id>
                            <xsl:attribute name="value" namespace="" select="'usagent'"/>
                        </id>
                        <xsl:for-each select="ns0:id">
                            <identifier>
                                <system>
                                    <xsl:for-each select="@root">
                                        <xsl:attribute name="value" namespace="" select="xs:string(xs:anyURI(fn:concat('urn:oid:', fn:string(.))))"/>
                                    </xsl:for-each>
                                </system>
                                <value>
                                    <xsl:for-each select="@extension">
                                        <xsl:attribute name="value" namespace="" select="fn:string(.)"/>
                                    </xsl:for-each>
                                </value>
                            </identifier>
                        </xsl:for-each>
                        <type>
                            <coding>
                                <system>
                                    <xsl:attribute name="value" namespace="" select="$var7_http___hl__org_fhir_us_spl_Cod_as_string"/>
                                </system>
                                <code>
                                    <xsl:attribute name="value" namespace="" select="'USAgent'"/>
                                </code>
                            </coding>
                        </type>
                        <xsl:for-each select="ns0:name">
                            <name>
                                <xsl:for-each select="(./node())[fn:boolean(self::text())]">
                                    <xsl:attribute name="value" namespace="" select="fn:string(.)"/>
                                </xsl:for-each>
                            </name>
                        </xsl:for-each>
                        <xsl:for-each select="ns0:telecom">
                            <xsl:variable name="var4_resultof_parseTelecom" as="node()?">
                                <xsl:call-template name="user:parseTelecom">
                                    <xsl:with-param name="SimpleTEL" as="node()">
                                        <Simple-TEL xmlns="urn:hl7-org:v3">
                                            <xsl:sequence select="(./@node(), ./node())"/>
                                        </Simple-TEL>
                                    </xsl:with-param>
                                </xsl:call-template>
                            </xsl:variable>
                            <xsl:for-each select="$var4_resultof_parseTelecom">
                                <telecom>
                                    <xsl:sequence select="(./@node(), ./node())"/>
                                </telecom>
                            </xsl:for-each>
                        </xsl:for-each>
                    </Organization>
                </contained>
            </xsl:for-each>
            <xsl:for-each select="$LabelerOrganization/ns0:id">
                <identifier>
                    <system>
                        <xsl:for-each select="@root">
                            <xsl:attribute name="value" namespace="" select="xs:string(xs:anyURI(fn:concat('urn:oid:', fn:string(.))))"/>
                        </xsl:for-each>
                    </system>
                    <value>
                        <xsl:for-each select="@extension">
                            <xsl:attribute name="value" namespace="" select="fn:string(.)"/>
                        </xsl:for-each>
                    </value>
                </identifier>
            </xsl:for-each>
            <type>
                <coding>
                    <system>
                        <xsl:attribute name="value" namespace="" select="$var7_http___hl__org_fhir_us_spl_Cod_as_string"/>
                    </system>
                    <code>
                        <xsl:attribute name="value" namespace="" select="'Labeler'"/>
                    </code>
                </coding>
            </type>
            <xsl:for-each select="$LabelerOrganization/ns0:name">
                <name>
                    <xsl:for-each select="(./node())[fn:boolean(self::text())]">
                        <xsl:attribute name="value" namespace="" select="fn:string(.)"/>
                    </xsl:for-each>
                </name>
            </xsl:for-each>
            <xsl:for-each select="$var6_assignedEntity/ns0:assignedOrganization/ns0:assignedEntity/ns0:assignedOrganization/ns0:addr">
                <address>
                    <xsl:for-each select="ns0:streetAddressLine">
                        <line>
                            <xsl:for-each select="(./node())[fn:boolean(self::text())]">
                                <xsl:attribute name="value" namespace="" select="fn:string(.)"/>
                            </xsl:for-each>
                        </line>
                    </xsl:for-each>
                    <xsl:for-each select="ns0:city">
                        <city>
                            <xsl:for-each select="(./node())[fn:boolean(self::text())]">
                                <xsl:attribute name="value" namespace="" select="fn:string(.)"/>
                            </xsl:for-each>
                        </city>
                    </xsl:for-each>
                    <xsl:for-each select="ns0:state">
                        <state>
                            <xsl:for-each select="(./node())[fn:boolean(self::text())]">
                                <xsl:attribute name="value" namespace="" select="fn:string(.)"/>
                            </xsl:for-each>
                        </state>
                    </xsl:for-each>
                    <xsl:for-each select="ns0:postalCode">
                        <postalCode>
                            <xsl:for-each select="(./node())[fn:boolean(self::text())]">
                                <xsl:attribute name="value" namespace="" select="fn:string(.)"/>
                            </xsl:for-each>
                        </postalCode>
                    </xsl:for-each>
                    <xsl:for-each select="ns0:country">
                        <country>
                            <xsl:for-each select="(./node())[fn:boolean(self::text())]">
                                <xsl:attribute name="value" namespace="" select="fn:string(.)"/>
                            </xsl:for-each>
                        </country>
                    </xsl:for-each>
                </address>
            </xsl:for-each>
            <xsl:for-each select="$LabelerOrganization/ns0:contactParty">
                <contact>
                    <xsl:for-each select="ns0:contactPerson/ns0:name">
                        <name>
                            <text>
                                <xsl:for-each select="(./node())[fn:boolean(self::text())]">
                                    <xsl:attribute name="value" namespace="" select="fn:string(.)"/>
                                </xsl:for-each>
                            </text>
                        </name>
                    </xsl:for-each>
                    <xsl:for-each select="ns0:telecom">
                        <xsl:variable name="var5_resultof_parseTelecom" as="node()?">
                            <xsl:call-template name="user:parseTelecom">
                                <xsl:with-param name="SimpleTEL" as="node()">
                                    <Simple-TEL xmlns="urn:hl7-org:v3">
                                        <xsl:sequence select="(./@node(), ./node())"/>
                                    </Simple-TEL>
                                </xsl:with-param>
                            </xsl:call-template>
                        </xsl:variable>
                        <xsl:for-each select="$var5_resultof_parseTelecom">
                            <telecom>
                                <xsl:sequence select="(./@node(), ./node())"/>
                            </telecom>
                        </xsl:for-each>
                    </xsl:for-each>
                    <xsl:for-each select="ns0:addr">
                        <address>
                            <xsl:for-each select="ns0:streetAddressLine">
                                <line>
                                    <xsl:for-each select="(./node())[fn:boolean(self::text())]">
                                        <xsl:attribute name="value" namespace="" select="fn:string(.)"/>
                                    </xsl:for-each>
                                </line>
                            </xsl:for-each>
                            <xsl:for-each select="ns0:city">
                                <city>
                                    <xsl:for-each select="(./node())[fn:boolean(self::text())]">
                                        <xsl:attribute name="value" namespace="" select="fn:string(.)"/>
                                    </xsl:for-each>
                                </city>
                            </xsl:for-each>
                            <xsl:for-each select="ns0:state">
                                <state>
                                    <xsl:for-each select="(./node())[fn:boolean(self::text())]">
                                        <xsl:attribute name="value" namespace="" select="fn:string(.)"/>
                                    </xsl:for-each>
                                </state>
                            </xsl:for-each>
                            <xsl:for-each select="ns0:postalCode">
                                <postalCode>
                                    <xsl:for-each select="(./node())[fn:boolean(self::text())]">
                                        <xsl:attribute name="value" namespace="" select="fn:string(.)"/>
                                    </xsl:for-each>
                                </postalCode>
                            </xsl:for-each>
                            <xsl:for-each select="ns0:country">
                                <country>
                                    <xsl:for-each select="(./node())[fn:boolean(self::text())]">
                                        <xsl:attribute name="value" namespace="" select="fn:string(.)"/>
                                    </xsl:for-each>
                                </country>
                            </xsl:for-each>
                        </address>
                    </xsl:for-each>
                </contact>
            </xsl:for-each>
        </Organization>
    </xsl:template>
    <xsl:template name="vmf:vmf8_inputtoresult">
        <xsl:param name="input" select="()"/>
        <xsl:choose>
            <xsl:when test="$input='tel'">
                <xsl:copy-of select="'phone'"/>
            </xsl:when>
            <xsl:when test="$input='mailto'">
                <xsl:copy-of select="'email'"/>
            </xsl:when>
            <xsl:when test="$input='fax'">
                <xsl:copy-of select="'fax'"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:copy-of select="'url'"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    <xsl:output method="xml" encoding="UTF-8" byte-order-mark="no" indent="yes"/>
    <xsl:template match="/">
        <Bundle xmlns="http://hl7.org/fhir" xmlns:xhtml="http://www.w3.org/1999/xhtml">
            <type>
                <xsl:attribute name="value" namespace="" select="'collection'"/>
            </type>
            <xsl:for-each select="ns0:document/ns0:author/ns0:assignedEntity/ns0:representedOrganization">
                <xsl:variable name="var1_resultof_createLabelerOrganization" as="node()?">
                    <xsl:call-template name="user:createLabelerOrganization">
                        <xsl:with-param name="LabelerOrganization" as="node()">
                            <LabelerRequest.LabelerOrganization xmlns="urn:hl7-org:v3">
                                <xsl:sequence select="(./@node(), ./node())"/>
                            </LabelerRequest.LabelerOrganization>
                        </xsl:with-param>
                    </xsl:call-template>
                </xsl:variable>
                <xsl:for-each select="$var1_resultof_createLabelerOrganization">
                    <entry>
                        <resource>
                            <Organization>
                                <xsl:sequence select="(./@node(), ./node())"/>
                            </Organization>
                        </resource>
                    </entry>
                </xsl:for-each>
            </xsl:for-each>
        </Bundle>
    </xsl:template>
</xsl:stylesheet>

CodePudding user response:

Your stylesheet specifies version="2.0", and it uses some constructs that require XSLT 2.0, for example select="()".

An XSLT 1.0 processor is going to handle this in "forwards-compatible mode". This is an area of the W3C spec that isn't always implemented very accurately, but in essence, an XSLT 1.0 processor seeing a 2.0 stylesheet is supposed to ignore things it doesn't understand. That means, for example that when you write <xsl:attribute name="code" select="fn:string(.)"/>, it will ignore the select attribute and output an attribute with the value "".

The other problem you can get with stylesheets generated by Altova Mapforce is that they contain calls to Altova-specific extensions functions. But I don't see any examples of that here -- as far as I can tell, this code should execute under a standard XSLT 2.0 processor such as Saxon. If you want to run this in node.js, try installing SaxonJS [disclaimer, this is my company's product].

  • Related