Radoslaw Krasimirow
Radoslaw Krasimirow

Reputation: 1873

Saxon XSLT 2.0 casting error the doesnt make sense for me

I am trying to perform simple transformation. The error reported by the proccessor is: An attribute node (name) cannot be created after the children of the containing element. The error is pointing to this line <xsl:apply-templates select="@*|node()"/> into the last template.

EDIT#1: This is the input:

<root>
    <processor>../../library/saxon-he-9-6-0-7j/saxon9he.jar</processor>
    <test-case name="test-case-1">
        <object-under-test category="template" name="text-align"/>
        <parameters>
            <input name="text">text</input>
            <input name="min-lenght">8</input>
            <input name="align">left</input>
            <output name="result"/>
        </parameters>
        <criteria>
            <criterion class="equal" to="'text    '"/>
        </criteria>
    </test-case>
</root>

This is the XSL:

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xslAlt="dummy" version="1.0">
    <xsl:namespace-alias stylesheet-prefix="xslAlt" result-prefix="xsl"/>
    <!--~~~-->
    <xsl:template match="root">
        <xslAlt:stylesheet version="1.0">
            <xslAlt:output method="xml"/>
            <xslAlt:include href="../../../product/templates.xsl"/>
            <xslAlt:template name="root" match="/">
                <xsl:apply-templates select="test-case"/>
            </xslAlt:template>
        </xslAlt:stylesheet>
    </xsl:template>
    <!--~~-->
    <xsl:template match="test-case">
        <test-case name="{concat('test-case-', string(position()))}">
            <xsl:variable name="test-case-return" select="concat('test-case-',string(position()),'-return')"/>
            <xslAlt:variable name="{$test-case-return}">
                <xslAlt:call-template name="{object-under-test/@name}">
                    <xsl:for-each select="parameters/input">
                        <xsl:choose>
                            <xsl:when test="string(number()) = 'NaN'">
                                <xslAlt:with-param name="{@name}" select="'{.}'"/>
                            </xsl:when>
                            <xsl:otherwise>
                                <xslAlt:with-param name="{@name}" select="{.}"/>
                            </xsl:otherwise>
                        </xsl:choose>
                    </xsl:for-each>
                </xslAlt:call-template>
            </xslAlt:variable>
            <!--~~-->
            <xslAlt:variable name="result" select="translate(${$test-case-return},{string('$space')},{string('$nbsp')})"/>
            <xsl:apply-templates select="@*|node()"/>
        </test-case>
    </xsl:template>
    <!--~~-->
    <xsl:template match="criteria">
        <criteria>
            <xslAlt:variable name="test-result">
                <xslAlt:choose>
                    <xslAlt:when test="{translate(criterion/@to,'&#32;','&#160;')} = $result">TEST-PASSED</xslAlt:when>
                    <xslAlt:otherwise>TEST-FAILED</xslAlt:otherwise>
                </xslAlt:choose>
            </xslAlt:variable>
            <xsl:apply-templates select="@*|node()"/>
        </criteria>
    </xsl:template>
    <!--~~-->
    <xsl:template match="@to">
        <xsl:attribute name="to">
            <xsl:value-of select="translate(.,'&#32;','&#160;')"/>
            <!--translate  replace-->
        </xsl:attribute>
        <xsl:attribute name="result">{<xsl:value-of select="string('$test-result')"/></xsl:attribute>
    </xsl:template>
    <!--~~-->
    <xsl:template match="parameters/output">
        <output name="{@name}">
            <xslAlt:value-of select="$result"/>
        </output>
    </xsl:template>
    <!--~~-->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/><!--THE ERROR IS POINTING HERE!!!-->
        </xsl:copy>
    </xsl:template>
    <!--~~-->
</xsl:stylesheet>

Upvotes: 0

Views: 101

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 116992

The error reported by the proccessor is: An attribute node (name) cannot be created after the children of the containing element.

This is not a "casting error". What it says is that you are trying to create an attribute after some children have already been created.

AFAICT, it happens here:

<xsl:template match="test-case">
    <test-case name="{concat('test-case-', string(position()))}">

        <!--here child nodes are being created!!! ~-->

        <xsl:apply-templates select="@*|node()"/>
    </test-case>
</xsl:template>

If you change (line #35):

<xsl:apply-templates select="@*|node()"/>

to:

<xsl:apply-templates select="node()"/>

the error will go away, because now it will stop trying to copy the existing attributes. You would not want this to happen anyway, since it would overwrite the name attribute you have created yourself.

Caveat:
I have not examined your stylesheet in-depth.

Upvotes: 2

Related Questions