xsltxsdaltovaxmlspy

xslt expects element instead of xsl:for-each


Since I am a beginner in xslt/xsd-programming, I am using XMLSpy to create a xml2xml transformation. For both xml I have got a xsd. Unfortunately, the following code piece is not valid.

<xsl:template match="/">
    <table xsi:noNamespaceSchemaLocation="table.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <xsl:for-each select="table/body/line">
            <row>
            </row>
        </xsl:for-each>
    </table>
</xsl:template>

The error message says that the row element is expected after table.
Details (translated): element <xsl:for-each> was not expected of type {anonymous} of element <table>.

The problem can be solved by removing the reference to the xsd or removing the for-each statement.
However, I cannot figure out what is wrong. To my understanding the for-each-loop should just repeat the <row> tags for each line in the first xml.
Here is part of the xsd of the target.

<xs:element name="table">
    <xs:complexType>
        <xs:sequence>
            <xs:element ref="row" maxOccurs="unbounded"/>
            <xs:element ref="Metadata" minOccurs="0"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>

Solution

  • I suspect that Altova is using the presence of the attribute xsi:noNamespaceSchemaLocation="table.xsd" as a signal meaning "please validate this element against the schema in table.xsd"; which is not what you wanted, because of course it's not valid against that schema, as it contains XSLT instructions to create the required elements, rather than containing the required elements themselves.

    To work around this, try generating the attribute using xsl:attribute:

     <table xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
       <xsl:attribute name="xsi:noNamespaceSchemaLocation">table.xsd</xsl:attribute>
       <xsl:for-each select="table/body/line">
                <row/>
       </xsl:for-each>
     </table>