使用抽象类型对xsd模式验证xml

时间:2015-08-12 01:56:16

标签: xml xsd xsd-validation xmllint

任何人都可以解释与使用抽象类型定义验证文档相关的棘手行为吗?

此xml / xsd对正确验证:

basedef.xsd:

var trs = $("tbody tr")

for(var trx = 0; trx < trs.length; trx++) {
    if(trx + 1 % 5 == 0) {
        var tr = $(trs[trx])
        tr.css({
            .....
        })
    }
}

concrete.xsd:

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

concrete.xml:

<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>

然而,这不是:

testoper.xsd:

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

testoper.xml:

<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>

验证工具是libmxl2包中的xmllint。 我得到的错误如下:

<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>

2 个答案:

答案 0 :(得分:1)

基本上,您无法针对抽象类型验证实例。抽象类型的唯一用途是作为通过扩展或限制定义具体类型的基础。具体子类型可以在模式中定义(作为要验证的元素的类型),也可以在实例中定义(使用xsi:type属性),但必须在某处定义。

testoper.xml的验证失败只是因为xsi:type属性指定了一个不存在的类型。如果该属性存在,那么它必须命名该元素的声明类型的具体子类型。

此外,回应您的评论:

处理器是否使用xsi:noNamespaceSchemaLocation的任何帐户取决于您使用的处理器及其配置方式。请特别注意XSD第1部分第4.3.2节中的该子句:

  

xsi:schemaLocation和xsi:noNamespaceSchemaLocation [attributes]可以   发生在任何元素上。但是,如果这样的属性是错误的   在第一次出现元素或属性后发生   最初是元素信息项中的信息项   ·已验证·其[名称空间名称]的地址。根据   第1层规则:模式有效性评估核心摘要   (§4.1),相应的模式可能会延迟组装,但是   否则稳定·评估·。架构位置   属性可以出现在任何元素上,并且可以进行处理   逐渐发现,它们的影响基本上是全球性的   ·评定·。定义和声明仍然有效   声明绑定的元素的范围。

这意味着在实例文档中间出现的xsi:schemaLocation属性存在问题。如果处理器考虑到它们,那么它必须将它们考虑在整个实例文档中,它不能通过验证的一半来改变模式。规范说你正在做的是“一个错误”,但是对于这实际意味着什么,处理器有所不同,这是多么模糊。

答案 1 :(得分:1)

但......如果我们定义:

<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>

这将验证

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

有问题
  xsi:noNamespaceSchemaLocation="concrete.xsd"

但基本上,是的,我完全同意使用抽象类型来定义一个看起来不错的元素,使用它们作为基类型看起来更合理。