控制 XSD 类型替换的混乱

问题描述 投票:0回答:1

以下 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
值.

xml xsd
1个回答
0
投票

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=""/>   

修复它。

© www.soinside.com 2019 - 2024. All rights reserved.