How can I specify an XML schema for an instance document like this:
Thanks to XML Schema 1.1, there is a way to enforce your requirement without having to import the xsi
namespace and hack polymorphism into your XML document. XML Schema 1.1 brought two new components, assertions and type alternatives, providing the xs:assert
and xs:alternative
elements. They have a @test
attribute in which conditions and constraints are being specified as XPath 2.0 expressions.
Even though xs:alternative
is obviously meant to be the solution to your problem, I for my part have not yet succeeded in assigning alternative types based on an element's position. (The schema parser's understanding of node contexts seems to differ from the one I would expect based on the validated XML document structure.)
Anyway, you can enforce your constraints using xs:assert
:
The use of attribute @xpathDefaultNamespace
may not be necessary if your schema's namespace is null, but must be set to ##targetNamespace
if you schema defines one, otherwise evaluation of the element name will fail.
Note: Obviously, for this to work it is necessary to use a validator which supports XML Schema 1.1. When using, say, OxygenXML, you can just set the default XML schema version to 1.1 in the XML / XML Parser / XML Schema preference page. When using Xerces as a validator, an additional feature must be activated:
http://apache.org/xml/features/validation/cta-full-xpath-checking
. Otherwise it will fail to evaluate most of the XPath you come up with because it uses an insufficient subset by default.