简体   繁体   English

针对具有抽象类型的xsd模式验证xml

[英]validating xml against xsd schema with abstract types

Can anyone offer any explanation for the tricky behavior related to validating documents with abstract type definition? 谁能提供与使用抽象类型定义验证文档有关的棘手行为的任何解释?

This xml/xsd pair validates properly: 此xml / xsd对正确验证:

basedef.xsd: basedef.xsd:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
  <xsd:complexType name="abstractType" abstract="true"/>
</xsd:schema>

concrete.xsd: concrete.xsd:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" >

  <xsd:include schemaLocation="basedef.xsd"/>

  <xsd:element type="abstractType" name="object" />

  <xsd:complexType name="concreteType" >
      <xsd:complexContent>
          <xsd:extension base="abstractType">
              <xsd:sequence >
                  <xsd:element type="xsd:string" name="field" />
              </xsd:sequence>
          </xsd:extension>
      </xsd:complexContent>
  </xsd:complexType>
</xsd:schema>

concrete.xml: concrete.xml:

<object xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="concreteType">
  <field>value</field>
</object>

This however, does not: 但是,这不会:

testoper.xsd: testoper.xsd:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:include schemaLocation="basedef.xsd"/>

  <xsd:complexType name="dbOper">
    <xsd:sequence>
      <xsd:element name="operation-create" type="createOperation"/>
    </xsd:sequence>
  </xsd:complexType>
  <xsd:complexType name="createOperation">
    <xsd:sequence>
      <xsd:element name="object" type="abstractType"/>
    </xsd:sequence>
  </xsd:complexType>
  <xsd:element name="dbOper" type="dbOper"/>
</xsd:schema>

testoper.xml: testoper.xml:

<dbOper>
  <operation-create>
    <object xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="concreteType" xsi:noNamespaceSchemaLocation="concrete.xsd">
      <field>value</field>
    </object>
  </operation-create>
</dbOper>

The validation tool is xmllint from the libmxl2 package. 验证工具是libmxl2软件包中的xmllint。 Errors I'm getting are as follows: 我遇到的错误如下:

testoper.xml:3: element object: Schemas validity error : Element 'object', attribute '{w3.org/2001/XMLSchema-instance}type': 
    **The QName value 'concreteType' of the xsi:type attribute does not resolve to a type definition**.

testoper.xml:3: element object: Schemas validity error : 
    Element 'object': **The type definition is abstract.** 

Essentially, you can't validate instances against an abstract type. 本质上,您不能针对抽象类型验证实例。 The only use for an abstract type is as a base for defining concrete types by extension or restriction. 抽象类型的唯一用途是作为通过扩展或限制定义具体类型的基础。 The concrete subtype can be defined either in the schema (as the type of the element you want to validate), or in the instance (using the xsi:type attribute) but it must be defined somewhere. 可以在模式(作为要验证的元素的类型)中或在实例(使用xsi:type属性)中定义具体的子类型,但必须在某处定义。

Validation of testoper.xml is failing simply because the xsi:type attribute names a nonexistent type. 仅仅因为xsi:type属性命名了一个不存在的类型,导致testoper.xml的验证失败。 If the attribute is present then it must name a concrete subtype of the declared type of the element. 如果存在该属性,则它必须命名元素声明类型的具体子类型。

Further, in response to your comment: 此外,针对您的评论:

Whether or not the processor takes any account of the xsi:noNamespaceSchemaLocation depends on what processor you are using and how it is configured. 处理器是否考虑xsi:noNamespaceSchemaLocation取决于您使用的处理器以及它的配置方式。 Note in particular this clause in XSD Part 1 section 4.3.2: 请特别注意XSD第1部分第4.3.2节中的此子句:

xsi:schemaLocation and xsi:noNamespaceSchemaLocation [attributes] can occur on any element. xsi:schemaLocation和xsi:noNamespaceSchemaLocation [属性]可以出现在任何元素上。 However, it is an error if such an attribute occurs after the first appearance of an element or attribute information item within an element information item initially ·validated· whose [namespace name] it addresses. 但是,如果这样的属性出现在最初验证其元素[名称空间名称]的元素信息项中的元素或属性信息项的首次出现之后,则会出现错误。 According to the rules of Layer 1: Summary of the Schema-validity Assessment Core (§4.1), the corresponding schema may be lazily assembled, but is otherwise stable throughout ·assessment·. 根据第1层的规则:模式有效性评估核心摘要(第4.1节),相应的模式可能是延迟组装的,但在整个评估过程中都是稳定的。 Although schema location attributes can occur on any element, and can be processed incrementally as discovered, their effect is essentially global to the ·assessment·. 尽管架构位置属性可以出现在任何元素上,并且可以根据发现进行增量处理,但是它们的影响对于评估而言基本上是全局的。 Definitions and declarations remain in effect beyond the scope of the element on which the binding is declared. 定义和声明仍然超出声明绑定的元素的范围。

What this means is that an xsi:schemaLocation attribute appearing half way through the instance document is problematic. 这意味着在实例文档中途出现的xsi:schemaLocation属性是有问题的。 If the processor takes account of them, then it must take account of them for the whole instance document, it can't change the schema half way through validating. 如果处理器考虑了它们,那么它对于整个实例文档都必须考虑它们,那么它就不能在验证过程中半途更改架构。 The spec says that what you are doing is "an error", but it's notoriously vague as to what this actually means, and processors vary. 规范说您正在做的是“错误”,但是实际上这意味着什么,并且众所周知,处理器也各不相同。

But... If we define: 但是...如果我们定义:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:include schemaLocation="concrete.xsd"/>

  <xsd:complexType name="dbOper">
    <xsd:sequence>
      <xsd:element name="operation-create" type="createOperation"/>
    </xsd:sequence>
  </xsd:complexType>
  <xsd:complexType name="createOperation">
    <xsd:sequence>
      <xsd:element name="object" type="abstractType"/>
    </xsd:sequence>
  </xsd:complexType>
  <xsd:element name="dbOper" type="dbOper"/>
</xsd:schema>

This will validate 这将验证

xmllint --noout --path . --schema testoper2.xsd test.xml test.xml 

There is a problem with 有问题

  xsi:noNamespaceSchemaLocation="concrete.xsd"

But basically, yes, I fully agree using abstract types to define an element looks like a bad idea, using them as base types looks more sensible. 但是,基本上,是的,我完全同意使用抽象类型来定义元素似乎是个坏主意,因为将它们用作基本类型看起来更明智。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM