Search code examples
xsltxslt-2.0saxonxsd-1.1

Does XSLT schema aware validation work with "alternative"


(This is a completely rewritten question)

I'm using Saxon C# API saxon9ee-api library to "compile" (for the purposes of validation) schema aware xslts against their schema (I was using Oxygen, but actually that adds a layer of configuration that makes things more complex). The objective is to formalise a "style" of XSD (which will be autogenerated) and a "style" of XSLT (which will be written by humans) that catches as many errors in the XSLT should the XSD change.

lets take an xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
    xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1">

  <xs:complexType name="TRIANGLETYPE">
    <xs:sequence>
    </xs:sequence>
    <xs:attribute name="rotation" type="xs:int"/>
    <xs:attribute name="x" type="xs:int"/>
    <xs:attribute name="y" type="xs:int"/>
  </xs:complexType>
  <xs:element name="TRIANGLE" type="TRIANGLETYPE">
    <!--<xs:alternative type="TRIANGLETYPE"/>-->
  </xs:element>
</xs:schema>

and take an XSLT

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
    exclude-result-prefixes="xs msxsl"
    version="2.0">

  <xsl:output method="xml" indent="yes" encoding="UTF-8" version="1.0"/>

  <xsl:import-schema schema-location="MessingAbout.xsd"/>
  <xsl:template match="schema-element(TRIANGLE)">
    <foo>
      <xsl:value-of select="@rotation"/>
    </foo>
  </xsl:template>
</xsl:stylesheet>

and this will behave nicely...this one validates, if I change the "rotation" reference to "rotation1" then I get

The complex type Q{}TRIANGLETYPE does not allow an attribute named rotation1

Which is what I want. But if I change the XSD to say

  <xs:element name="TRIANGLE">
    <xs:alternative type="TRIANGLETYPE"/>
  </xs:element>

instead of the explicit type

  <xs:element name="TRIANGLE" type="TRIANGLETYPE">

then the inference on the XSLT "fails" - in the sense that it will not detect the type fault in the XSLT when it refers to the attribute "rotation1", which is not defined.

So the questions are

  • Does "alternative" basically short circuit the type checking? (even if there is only 1 alternative - do I understand the semantics of alternative?)
  • If so is there a way around this (i.e. its been suggested to use "element()" which I'll try.
  • additionally, is there some options to raise warnings for sections of code that cannot/has not been type checked, I'd like to exclude the false positive scenario by detecting this as a warning.

an additional question, is there any good tutorials/books etc on schema aware XSLTs, short of trying to comprehend the specification, there is pitifully little out there.


Solution

  • I only tested with Saxon 10 EE but there indeed xsl:template match="element(TRIANGLE, TRIANGLETYPE)" seems a way to trigger the warning of e.g. "SXWN9000 The complex type Q{}TRIANGLETYPE does not allow an attribute named rotation1".