禁用xsd:anyType元素

时间:2017-11-15 09:34:49

标签: xml validation xsd

使用类型为xs:anyType的元素的XML Schema。

<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:anyTyp e元素的XML架构进行验证。

  

E [Xerces] cvc-elt.4.2:无法解析&#39; ForeignType&#39;到元素的类型定义&#39;任何&#39;。

使用<xs:any/>元素而不是<element type="xs:anyType"/>时,可以使用 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. 如何在xsi:type元素中禁用xs:anyType验证(如processContents="skip
  2. 为什么<xs:any/><element type="xs:anyType"/>
  3. 存在差异

1 个答案:

答案 0 :(得分:3)

  

如何在xsi:type元素中禁用xs:anyType验证(例如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无效。

  

为什么<xs:any/><element type="xs:anyType"/>

存在差异

内置类型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"/>

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

随着设计决策的进行,那个看起来非常简单。即使是XML Schema工作组(从来没有人认为具有很多怀疑的特设机构)也认为这种特殊用途的机器是不必要的。

在基于属性语法构建的模式语言中,继承的属性可以用于参数化元素和/或类型,这样的机制将是语言的自然部分,并且具有lax / strict / skip处理的参数可能是有意义的。但是,广泛使用的XSD和任何其他模式语言都不是基于属性语法构建的。