The following XSD defines the complex types Base
, which specifies block=""
, and Derived
, which extends Base
and also specifies block=""
.
<?xml version="1.0" encoding="utf-8"?>
<xs:schema
targetNamespace ="http://example.org/scratch-type-substitution"
xmlns ="http://example.org/scratch-type-substitution"
xmlns:xs ="http://www.w3.org/2001/XMLSchema"
blockDefault ="">
<xs:complexType name="Base" block=""/>
<xs:complexType name="Derived" block="">
<xs:complexContent>
<xs:extension base="Base"/>
</xs:complexContent>
</xs:complexType>
<xs:element name="root">
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element name="base" type="Base"/>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
The following instance is valid per the XSD. It specifies a Base
type element which is explicitly substituted by the Derived
type via xsi:type
:
<pre:root
xmlns:pre="http://example.org/scratch-type-substitution"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<base xsi:type="pre:Derived"/>
</pre:root>
However, if the attribute blockDefault="#all"
is added to <schema>
, the instance fails validation. In particular, the .NET 8.0 XmlDocument
method Load
emits:
The xsi:type attribute value 'http://example.org/scratch-type-substitution:Derived' is not valid for the element 'base', either because it is not a type validly derived from the type in the schema, or because it has xsi:type derivation blocked.
I don't think the former could be true. If the latter is true, I don't understand why, given that the PSVI information for both types' resolved block
attribute values is 'Empty' -and- that an empty string (or any value) overrides the blockDefault
value.
The Saxon schema validator gives the same results. Here is the error message:
Validation error on line 5 column 33 of test.xml: FORG0001: The xsi:type is not validly derived from the declared type. Derivation of the requested type Q{http://example.org/scratch-type-substitution}Derived is blocked either by the base type Q{http://example.org/scratch-type-substitution}Derived or by the element declaration See https://www.w3.org/TR/xmlschema11-1/#cvc-elt clause 4.3
I think the last bit gives the clue: although the type declaration overrides blockDefault
, the element declaration doesn't.
Changing the element declaration to
<xs:element name="base" type="Base" block=""/>
fixes it.