XML不会抛出架构错误

问题描述:

我很努力去理解为什么我的xml和架构不起作用。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:当分钟发生是1

我做

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

难道不应该抛出异常,因为人口从XML文件丢失一切都对吗?

你正在做几件事。这里有几个你可能要添加到列表:

  • 您创建和定义应该使用你必须控制权的域名命名空间。除非你拥有域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在符合性要求方面有点过于慌张。)或验证程序可能允许您声明文档需要在http://www.w3schools.com命名空间中有animals元素,并且如果是别的,应该提出错误。如果你的验证器没有给你任何控制它开始工作的控制,让供应商知道你宁愿有一些控制,同时寻找一个不同的验证器。

[P.S.另请参阅迈克尔凯对此答案的评论,以备考虑另一重要问题。]

+2

我只想补充一点迈克尔的列表。检查你是否真的在调用模式验证器。很抱歉,如果这听起来很愚蠢,但只是将schemaLocation添加到XML文档中并不会自动将您的XML解析器转换为模式验证器。 – 2013-02-28 14:53:09

您的模式看起来不正确 - 您不能直接在xs:element(也不是直接在xs:complexType之内)放置xs:element

我认为,你想要的是

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