xslt-1.0biztalkbiztalk-2013

How to fix 'Errors were reported during stylesheet compilation' in XSLT?


I have this SaxonApiException when I run my XSLT code on https://xslttest.appspot.com/. It return this error :

net.sf.saxon.s9api.SaxonApiException: Errors were reported during stylesheet compilation

I tried on another online tester https://www.freeformatter.com/xsl-transformer.html but I got the same error. I tried to split my XSLT code. First part with the process of extract ZipCode in Wages and second part with the process of extract ZipCode in Addresses. Both works when they're separated so I think I made a mistake in the 'choose' element but cannot find it.

Here is my XSLT code...

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/EmployeeUDM_Response/Return/Employee">
  <xsl:for-each select="./Wages/Wage">
    <xsl:choose>
      <xsl:when test="DissimelarZipCode != ''">
        <xsl:value-of select="DissimelarZipCode" />
      </xsl:when>
      <otherwise>
        <xsl:for-each select="./Addresses/Address" />
          <!-- year -->
          <xsl:sort select="substring(StartDate, 1, 4)" order="descending" data-type="number"/>
          <!-- month -->
          <xsl:sort select="substring(StartDate, 6, 2)" order="descending" data-type="number"/>
          <!-- day -->
          <xsl:sort select="substring(StartDate, 9, 2)" order="descending" data-type="number"/>
          <xsl:if test="position() = 1">
            <xsl:value-of select="./ZipCode" />
          </xsl:if>
      </otherwise>
    </xsl:choose>
  </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

...and my XML file

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl"?>
<EmployeeUDM_Response xmlns:ns0="http://ESB/Schemas/v2/EmployeeUDM">
    <Header Type="Employee" Source="Biztalk ESB" />
    <Return>
        <Employee>
            <Wages>
                <Wage>                  
                    <StartDate>2019-04-22T00:00:00.0000000+02:00</StartDate>
                    <EndDate>2019-05-01T00:00:00.0000000+02:00</EndDate>
                    <DissimelarZipCode>5430 NU</DissimelarZipCode>
                </Wage>
            </Wages>
                        <Addresses>
                <Address>
                    <StartDate>2014-01-01T00:00:00.0000000+02:00</StartDate>
                    <EndDate></EndDate>
                    <ZipCode>6099 EB</ZipCode>
                </Address>
                <Address>
                    <StartDate>2015-01-01T00:00:00.0000000+02:00</StartDate>
                    <EndDate></EndDate>
                    <ZipCode>5487 YR</ZipCode>
                </Address>
            </Addresses>
        </Employee>
    </Return>
</EmployeeUDM_Response>

I expected the output of the ZipCode in Wage (5430 NU in this case) or, if ZipCode in Wage is empty, the ZipCode in Address with the latest StartDate (5487 YR in this case)


Solution

  • 1. There should be <xsl:otherwise> instead of <otherwise>

    2. <xsl:sort> should be in <xsl:for-each> .(You have ended the loop in same line)

    3. To loop over Address, you will need xpath ../../Addresses/Address. Because at that time <Wage> is being processed. ( ../ will bring you up one level to parent node.)

    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    
        <xsl:template match="/EmployeeUDM_Response/Return/Employee">
            <xsl:for-each select="Wages/Wage">
                <xsl:choose>
                    <xsl:when test="DissimelarZipCode != ''">
                        <xsl:value-of select="DissimelarZipCode" />
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:for-each select="../../Addresses/Address">
                            <!-- year -->
                            <xsl:sort select="substring(StartDate, 1, 4)" order="descending"
                                data-type="number" />
                            <!-- month -->
                            <xsl:sort select="substring(StartDate, 6, 2)" order="descending"
                                data-type="number" />
                            <!-- day -->
                            <xsl:sort select="substring(StartDate, 9, 2)" order="descending"
                                data-type="number" />
                            <xsl:if test="position() = 1">
                                <xsl:value-of select="ZipCode" />
                            </xsl:if>
                        </xsl:for-each>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:for-each>
        </xsl:template>
    
    </xsl:stylesheet>
    

    https://xsltfiddle.liberty-development.net/pPzifpP