【问题标题】:Disable validation in xsd:anyType element在 xsd:anyType 元素中禁用验证
【发布时间】:2017-11-15 09:34:48
【问题描述】:

具有xs:anyType 类型元素的以下 XML 模式。

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
    <xs:element name="root">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="payloadAny" type="xs:anyType"/>                
            </xs:sequence>
        </xs:complexType>        
    </xs:element>
</xs:schema>

任何 XML 示例:

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <payloadAny>
        <anything>anyContent</anything>
    </payloadAny>
</root>

我们现在发现问题在于元素中的 xsi:type 属性是这样的:

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <payloadAny>
        <anything xsi:type="ForeignType">anyContent</anything>
    </payloadAny>
</root>

这个具有xsi:type 属性的XML 不再针对具有xs:anyType 元素的XML Schema 进行验证。

E [Xerces] cvc-elt.4.2:无法将“ForeignType”解析为元素“任何东西”的类型定义。

当使用&lt;xs:any/&gt; 元素而不是&lt;element type="xs:anyType"/&gt; 时,可以使用processContents 属性禁用验证。

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
    <xs:complexType name="any">
        <xs:sequence>
            <xs:any processContents="skip"/>
        </xs:sequence>
    </xs:complexType>      
    <xs:element name="root">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="payloadAny" type="any"/>                
            </xs:sequence>
        </xs:complexType>        
    </xs:element>
</xs:schema>

现在的问题如下:

  1. 如何在xs:anyType 元素中禁用xsi:type 验证(如processContents="skip
  2. 为什么&lt;xs:any/&gt;&lt;element type="xs:anyType"/&gt; 有这么大的区别?

【问题讨论】:

    标签: xml validation xsd


    【解决方案1】:

    如何在xs:anyType 元素中禁用xsi:type 验证(如processContents="skip"

    使用您在架构中定义的元素和类型结构,无法禁用架构处理器对xsi:type 属性的验证。 xsi:type 的声明被内置到每个符合 XSD 模式验证器中,并且无论何时严格或宽松地验证具有 xsi:type 属性的元素,都会找到该声明,并根据它验证 xsi:type 属性。一个有效的xsi:type 属性具有一个QName 值,该值标识模式中的类型定义。如果 QName 值没有标识类型定义,则该属性无效。

    从您报告的错误消息来看,您的架构似乎不包含扩展名称为 {}ForeignType 的类型。

    解决此问题的一种方法是为payloadAny 元素声明您似乎真正想要的类型,它不是xs:anyType,而是带有skip 通配符的不同类型。您的第二个模式示例显示了原理,尽管您的 {}any 类型与 xs:anyType 的不同之处在于只允许一个元素子元素,而不是允许许多元素和字符数据。 (如果你只想要一个元素作为payloadAny 的子元素,那么xs:anyType 就太松散了。)

    请注意,报告的错误不是声称anything 元素对ForeignType 类型无效,而是报告xsi:type 属性本身无效,因为它违反了本地约束元素的第4.2 条有效的。这反过来又使payloadAny 无效。

    为什么&lt;xs:any/&gt;&lt;element type="xs:anyType"/&gt; 有这么大的区别

    内置类型 xs:anyType 的行为(大致)就像使用以下声明在 XSD 1.0 架构中显示的架构文档声明:

    <xs:complexType name="anyType" mixed="true">
      <xs:annotation>
        <xs:documentation>
          Not the real urType, but as close an approximation as we can
          get in the XML representation</xs:documentation>
      </xs:annotation>
      <xs:sequence>
        <xs:any minOccurs="0" 
                maxOccurs="unbounded" 
                processContents="lax"/>
      </xs:sequence>
      <xs:anyAttribute processContents="lax"/>
    

    没有类似于processContentsxs:any 上的其他属性的复杂类型的参数化机制。为xs:anyType 添加此类机制将需要额外的临时机制(XSD 对您来说还不够复杂吗?您想要更多吗?)并且不会增加语言的表达能力。

    随着设计决策的进行,那个看起来很简单。甚至 XML Schema 工作组(从来没有一个对临时机制持怀疑态度的人)认为这种特殊用途的机制是不必要的。

    在基于属性语法的模式语言中,继承的属性可以用于参数化元素和/或类型,这种机制将是语言的自然部分,并且具有用于松弛/严格/跳过处理的参数可能是有意义的。但是 XSD 和任何其他广泛使用的模式语言都不是建立在属性语法之上的。

    【讨论】:

      猜你喜欢
      • 2020-10-08
      • 1970-01-01
      • 2021-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多