1

我很难理解为什么我的 xml 和架构不起作用。

架构:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3schools.com"
xmlns="http://www.w3schools.com"
elementFormDefault="qualified">

<xs:element name="animals">
    <xs:element name="animal">
        <xs:complexType>
            <xs:element name="species"/>
            <xs:element name="name"/>
            <xs:element name="population" minOccurs="1"/>
        </xs:complexType>

    </xs:element>
</xs:element>

XML:

<?xml version="1.0"?>

<animals xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="animals.xsd">
    <animal>
        <species>reptile</species>
        <name>cobra</name>

    </animal>
</animals>

它不应该抛出错误,因为当 min 发生为 1 时,xml 文件中缺少人口。

我做的一切正确吗?

4

2 回答 2

2

你做对了几件事。以下是您可能想要添加到该列表的更多内容:

  • 您创建和定义的命名空间应使用您有权控制的域名。除非您拥有 w3schools.com 域,否则最好不要在其空间中定义新的命名空间。如果您不拥有任何域,而只是想要一个示例,那么域 example.com 就是为此目的而保留的。或者您可以编写没有目标名称空间的模式。

  • xsi:schemaLocation 属性的值不是单个 URI,而是一系列 URI 对。在每一对中,第一项命名一个命名空间,第二项指定 XSD 验证器可以在哪里找到该命名空间的架构文档。因此,您希望该属性在您的 XML 文档实例中看起来像这样:

    xsi:schemaLocation="http://www.w3schools.com animals.xsd"
    

    或者,如果您重写架构文档以省略目标命名空间,请改用 xsi:noNamespaceSchemaLocation:

    xsi:noNamespaceSchemaLocation="animals.xsd"
    
  • 您的架构文档当前指定其目标命名空间是http://www.w3schools.com并且本地元素是完全限定的。因此,如果您希望架构处理器识别您显示的声明旨在应用于这些 XML 元素实例,那么您的 XML 中的所有元素都应该位于该名称空间中。所以在你的 XML 中,开始标签animals应该是这样的

    <animals xmlns="http://www.w3schools.com"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="
            http://www.w3schools.com animals.xsd
            ">
    
  • 正如您所展示的那样,我希望 XSD 验证器会反对 xsi:schemaLocation 的值没有偶数个令牌的事实。如果没有,那么您调用它的方式可能出现问题;但是,如果没有有关您正在使用的验证器以及如何调用它的更多信息,则很难确定。

  • 大多数 XSD 验证器以所谓的宽松验证模式开始工作:当他们在文档中看到具有元素声明的元素时,他们验证它,否则他们跳过它(或者在某些实现中,他们然后检查它的子元素对于他们可以验证的元素)。

    给定一个描述特定命名空间中元素的模式,以及一个使用不在该命名空间中的元素的 XML 文档,在宽松验证模式下启动的 XSD 验证器将无法判断文档实例中的元素是否有效。XSD 规范说,在这种情况下,validity文档元素的属性值为notKnown。大多数 XSD 验证器仅在遇到无效元素时才发出错误消息,因此大多数 XSD 验证器在没有与架构匹配的文档上以松散模式启动,不会发出任何错误消息。重要的是不要将此与文档对模式有效的判断混淆。它仅意味着该文档对架构无效。

    如果您发现这种行为不方便或令人困惑,就像许多人一样,您将需要检查您使用的验证器是否允许调用时间标志发出错误,或者至少发出警告,如果无法确认文档有效。(需要符合 XSD 1.1 的验证器才能做到这一点;XSD 1.0 在一致性要求方面有点模糊。)或者验证器可能允许您说文档必须animals在命名空间中有一个元素,http://www.w3schools.com并且错误应该如果有其他问题,请提出。如果您的验证器无法让您控制它如何开始工作,请让供应商知道您希望拥有一些控制权,同时寻找不同的验证器。

[PS 另请参阅 Michael Kay 对此答案的评论,以了解另一个需要考虑的重点。]

于 2013-02-28T13:55:50.820 回答
1

您的架构看起来不对 - 您不能xs:element直接放在里面xs:element(也不能直接放在里面xs:complexType)。

我认为你想要的是

<xs:schema 
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  targetNamespace="http://www.w3schools.com"
  xmlns="http://www.w3schools.com"
  elementFormDefault="qualified">

  <xs:element name="animals">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="animal" maxOccurs="unbounded">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="species"/>
              <xs:element name="name"/>
              <xs:element name="population" minOccurs="1"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

然后您的 XML 文件应使用架构命名空间:

<animals 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xsi:schemaLocation="animals.xsd" 
   xmlns="http://www.w3schools.com">
  <animal>
    <species>reptile</species>
    <name>cobra</name>
  </animal>
</animals>
于 2013-02-28T18:58:13.007 回答