没有匹配的全局声明可用于验证根

61

背景

使用架构验证XML文档。

问题

该问题的最简形式由两个文件显示。

XML 文档 file.xml

<?xml version="1.0"?>
<recipe xmlns:r="http://www.namespace.org/recipe">
  <r:description>
    <r:title>sugar cookies</r:title>
  </r:description>
</recipe>

XSD文档schema.xsd

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema
   version="1.0"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
   xmlns:r="http://www.namespace.org/recipe">

  <xsd:complexType name="recipe">
    <xsd:choice>
      <xsd:element name="description" type="descriptionType"
        minOccurs="1" maxOccurs="1" />
    </xsd:choice>
  </xsd:complexType>

  <xsd:complexType name="descriptionType">
    <xsd:all>
      <xsd:element name="title">
        <xsd:simpleType>
          <xsd:restriction base="xsd:string">
            <xsd:minLength value="5" />
            <xsd:maxLength value="55" />
          </xsd:restriction>
        </xsd:simpleType>
      </xsd:element>
    </xsd:all>
  </xsd:complexType>
</xsd:schema>

错误

来自xmllint的完整错误消息:

$ xmllint --noout --schema schema.xsd file.xml

file.xml:2: element recipe: Schemas validity error : Element 'recipe': No matching global declaration available for the validation root. file.xml fails to validate

问题

在给定的模式下,如何正确使用语法(或缺少哪些模式属性)才能确保可以成功验证给定的XML文档?

3个回答

31
您需要更改您的XML实例。您当前的实例说明了在命名空间http://www.namespace.org/recipe中有一个称为descriptiontype。然而,在您的XSD定义中,该命名空间中唯一公开的类型是称为recipedescriptionType的类型。

因此,请在XSD模式中定义一个名为description的类型,或者更改您的实例以正确引用recipe类型:

文件ns-changed.xml

<?xml version="1.0"?>
<r:recipe xmlns:r="http://www.namespace.org/recipe">
  <description>
    <title>sugar cookies</title>
  </description>
</r:recipe>

更新:这只是解决方案的一半,另一半在 @Aravind 的答案中。


我相信descriptiontitle等应该也有命名空间(例如:r:description)。 - rbaleksandar

20

recipe设为全局变量

仅全局元素定义能用作根元素。你的模式只有复杂类型,因此出现错误。

<xsd:complexType name="recipe">改为 <xsd:element name="recipe"><xsd:complexType>

模式文件:recipe-now-global.xsd

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema
   version="1.0"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
   xmlns:r="http://www.namespace.org/recipe">

  <xsd:element name="recipe">
    <xsd:complexType>
      <xsd:choice>
        <xsd:element name="description" type="descriptionType"
          minOccurs="1" maxOccurs="1" />
      </xsd:choice>
    </xsd:complexType>
  </xsd:element>

  <xsd:complexType name="descriptionType">
    <xsd:all>
      <xsd:element name="title">
        <xsd:simpleType>
          <xsd:restriction base="xsd:string">
            <xsd:minLength value="5" />
            <xsd:maxLength value="55" />
          </xsd:restriction>
        </xsd:simpleType>
      </xsd:element>
    </xsd:all>
  </xsd:complexType>
</xsd:schema>

点击此处了解更多信息。

注意:这仍然无法通过验证,因为您有一个不相关的命名空间错误...

$ cat file.xml | xmllint --noout --schema recipe-now-global.xsd -
-:3: element description: Schemas validity error : Element '{http://www.namespace.org/recipe}description': This element is not expected. Expected is ( description ).
- fails to validate

...但如果你像快速而不加整理地忽略该命名空间错误,它将会通过验证:

$ cat file.xml | sed 's/r://g' | xmllint --noout --schema recipe-now-global.xsd -
- validates

请查看tom redfern的答案,了解有关该命名空间问题的详细信息。


9
在你的xs:schema元素中添加elementFormDefault="qualified"。这意味着在架构中声明的本地元素被认为处于目标命名空间中。这本应是默认设置,你应该把它视为样板文件--反之,即本地元素不属于任何命名空间的情况非常罕见。 - Michael Kay

11

在我的实践中,我遇到了两种情况出现了No matching global declaration available for the validation root

  • 如果XSD文件中没有包含一个名为<xsd:element name="recipe" .../>的元素,请参考@aravind-r-yarram的答案

  • 如果XML文件中的<recipe/>元素没有包含xmlns属性,请添加xmlns属性以解决问题:

  <recipe xmlns="http://www.namespace.org/recipe">
      ...
  </recipe>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接