以下 XSD 定义了复杂类型
Base
,它指定 block=""
,以及 Derived
,它扩展 Base
并还指定 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>
以下实例根据 XSD 有效。 它指定一个
Base
类型元素,该元素通过 Derived
:显式替换为
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>
但是,如果将属性
blockDefault="#all"
添加到<schema>
,则实例将无法验证。 特别是,.NET 8.0 XmlDocument
方法 Load
发出:
xsi:type 属性值“http://example.org/scratch-type-substitution:Derived”对于元素“base”无效,因为它不是从架构中的类型有效派生的类型,或者因为它阻止了 xsi:type 派生。
我认为前者不可能是真的。 如果后者是真的,我不明白为什么,因为两种类型的已解析
block
属性值的 PSVI 信息都是“空” - 并且 - 空字符串(或任何值)会覆盖 blockDefault
值.
Saxon 模式验证器给出相同的结果。这是错误消息:
test.xml 第 5 行第 33 列验证错误:FORG0001: xsi:type 不是从声明的类型有效派生的。推导 请求的类型 Q{http://example.org/scratch-type-substitution}派生被阻止 通过基本类型 Q{http://example.org/scratch-type-substitution}派生或由 元素声明 请参阅 https://www.w3.org/TR/xmlschema11-1/#cvc-elt 第 4.3 条
我认为最后一点给出了线索:虽然类型声明覆盖了
blockDefault
,但元素声明却没有。
将元素声明更改为
<xs:element name="base" type="Base" block=""/>
修复它。