2013-05-05 61 views
2

我试图使用xs:choice元素,但在验证XSD文件时,我收到一个错误,我认为它与xs:choice元素有关。我已经搜索了很多这个问题,发现了一些类似的问题,但是没有人给我解答我寻找的答案以解决我的问题。XML模式xs:内部选择xs:序列

我想要做的是声明一个名为“数据”的元素,其子元素将是一个时间戳和一个传感器或提供者(这里是我试图使用选择元素的地方,因为我只是想要一个传感器或提供者元素作为时间戳的兄弟)。

以下XML是什么,我试图验证:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<experience xmlns="http://www.w3schools.com" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > 
<data> 
    <timestamp>123456789</timestamp> 
    <sensor origin="proximity" > 
     <x-axis>9</x-axis> 
     <y-axis>0</y-axis> 
     <z-axis>0</z-axis> 
     <w-axis>0</w-axis> 
    </sensor> 
</data> 
</experience> 

而为了验证这个XML,我写了下面XSD文件:

<?xml version="1.0" encoding="ISO-8859-1" ?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 

<!-- definition of attributes --> 
<xs:attribute name="origin" type="xs:string" /> 

<!-- definition of complex elements --> 
    <xs:element name="provider"> 
     <xs:complexType> 
      <xs:all> 
       <xs:element name="latitude" type="xs:float" /> 
       <xs:element name="longitude" type="xs:float" /> 
       <xs:element name="altitude" type="xs:float" /> 
       <xs:element name="bearing" type="xs:float" /> 
       <xs:element name="speed"  type="xs:float" /> 
      </xs:all> 
      <xs:attribute ref="origin" use="required"/> 
     </xs:complexType> 
    </xs:element> 

    <xs:element name="sensor"> 
     <xs:complexType> 
      <xs:all> 
       <xs:element name="x-axis" type="xs:float" /> 
       <xs:element name="y-axis" type="xs:float" /> 
       <xs:element name="z-axis" type="xs:float" /> 
       <xs:element name="w-axis" type="xs:float" /> 
      </xs:all> 
      <xs:attribute ref="origin" use="required"/> 
     </xs:complexType> 
    </xs:element> 

    <xs:element name="data"> 
     <xs:complexType> 
      <xs:sequence> 
       <xs:element ref="timestamp" minOccurs="1" maxOccurs="1" /> 

       <xs:choice> 
        <element ref="provider" /> 
        <element ref="sensor" /> 
       </xs:choice> 
      </xs:sequence> 
     </xs:complexType> 
    </xs:element> 

<!-- definition of main type --> 
    <xs:element name="experience"> 
     <xs:complexType> 
      <xs:sequence> 
       <xs:element ref="data" minOccurs="0" maxOccurs="unbounded"/> 
      </xs:sequence> 
     </xs:complexType> 
    </xs:element> 
</xs:schema> 

但是,一旦我上传文件,并尝试使用following w3 website来验证它,我得到以下错误:

file:/usr/local/XSV/xsvlog/tmph7cMmLuploaded:45:6: Invalid per cvc-complex-type.1.2.4: element {None}:element not allowed here (1) in element { http://www.w3.org/2001/XMLSchema }:choice, expecting [{ http://www.w3.org/2001/XMLSchema }:annotation,$,{ http://www.w3.org/2001/XMLSchema }:element,{ http://www.w3.org/2001/XMLSchema }:group,{ http://www.w3.org/2001/XMLSchema }:choice,{ http://www.w3.org/2001/XMLSchema }:sequence,{ http://www.w3.org/2001/XMLSchema }:any]:

我认为问题出在xs:choice元素中,但我可能是错的。

因为这是我第一次尝试使用xs:choice元素,所以我对我是否正确使用它有一些疑问。根据我在w3schools中的例子,但由于我打算在旁边使用它,我不知道它是否正确。

如果有人可以帮助我在这一个我会非常感激。

非常感谢提前。

回答

2

在您的XML和XSD中有一些移动目标;所以XSD和XML下面都是最低限度修饰的相互匹配...

修改XSD:

<?xml version="1.0" encoding="utf-8" ?> 
<!-- XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com) --> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3schools.com" targetNamespace="http://www.w3schools.com" elementFormDefault="qualified"> 

    <!-- definition of attributes --> 
    <xs:attribute name="origin" type="xs:string"/> 

    <!-- definition of complex elements --> 
    <xs:element name="provider"> 
     <xs:complexType> 
      <xs:all> 
       <xs:element name="latitude" type="xs:float"/> 
       <xs:element name="longitude" type="xs:float"/> 
       <xs:element name="altitude" type="xs:float"/> 
       <xs:element name="bearing" type="xs:float"/> 
       <xs:element name="speed" type="xs:float"/> 
      </xs:all> 
      <xs:attribute ref="origin" use="required"/> 
     </xs:complexType> 
    </xs:element> 

    <xs:element name="sensor"> 
     <xs:complexType> 
      <xs:all> 
       <xs:element name="x-axis" type="xs:float"/> 
       <xs:element name="y-axis" type="xs:float"/> 
       <xs:element name="z-axis" type="xs:float"/> 
       <xs:element name="w-axis" type="xs:float"/> 
      </xs:all> 
      <xs:attribute ref="origin" use="required"/> 
     </xs:complexType> 
    </xs:element> 
    <xs:element name="timestamp" type="xs:long"/> 

    <xs:element name="data"> 
     <xs:complexType> 
      <xs:sequence> 
       <xs:element ref="timestamp" minOccurs="1" maxOccurs="1"/> 

       <xs:choice> 
        <xs:element ref="provider"/> 
        <xs:element ref="sensor"/> 
       </xs:choice> 
      </xs:sequence> 
     </xs:complexType> 
    </xs:element> 

    <!-- definition of main type --> 
    <xs:element name="experience"> 
     <xs:complexType> 
      <xs:sequence> 
       <xs:element ref="data" minOccurs="0" maxOccurs="unbounded"/> 
      </xs:sequence> 
     </xs:complexType> 
    </xs:element> 
</xs:schema> 

修改XML:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<experience xmlns="http://www.w3schools.com" xmlns:tns="http://www.w3schools.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <data> 
     <timestamp>123456789</timestamp> 
     <sensor tns:origin="proximity"> 
      <x-axis>9</x-axis> 
      <y-axis>0</y-axis> 
      <z-axis>0</z-axis> 
      <w-axis>0</w-axis> 
     </sensor> 
    </data> 
</experience> 

因此,这是发生了什么:

  • 您的XML定义了一个默认的XML名称空间;因此,您的XSD必须定义匹配的名称空间,因此请参阅新的targetNamespace属性以及添加默认xmlns以匹配该属性。

  • 因为所有的元素都是合格的(因为在根级别使用默认的命名空间),那么你的架构应该使用elementFormDefault="qualified"

  • 您与选择的问题是,你有&lt;element ref="provider"等,这些需要xs:限定符(这是您提供的错误的要点)

  • 我在您的XSD中添加了timestamp元素。

尽管存在这些变化,问题现在变成了您的XML,特别是origin属性。既然你已经声明属性全局的,它必须在XSD的命名空间条件,因此我加入xmln:tns=...和fixin tns:origin=...

如果你真的不想改变XML,那么你的XSD要么定义本地属性(而不是引用),或者将该属性包装到组中并引用。所以这里是一个更新的XSD,它与原始XML相匹配。

<?xml version="1.0" encoding="utf-8" ?> 
<!-- XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com) --> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3schools.com" targetNamespace="http://www.w3schools.com" elementFormDefault="qualified"> 
    <xs:attributeGroup name="origin"> 
     <!-- definition of attributes --> 
     <xs:attribute name="origin" type="xs:string"/>  
    </xs:attributeGroup> 

    <!-- definition of complex elements --> 
    <xs:element name="provider"> 
     <xs:complexType> 
      <xs:all> 
       <xs:element name="latitude" type="xs:float"/> 
       <xs:element name="longitude" type="xs:float"/> 
       <xs:element name="altitude" type="xs:float"/> 
       <xs:element name="bearing" type="xs:float"/> 
       <xs:element name="speed" type="xs:float"/> 
      </xs:all> 
      <xs:attributeGroup ref="origin"/> 
     </xs:complexType> 
    </xs:element> 

    <xs:element name="sensor"> 
     <xs:complexType> 
      <xs:all> 
       <xs:element name="x-axis" type="xs:float"/> 
       <xs:element name="y-axis" type="xs:float"/> 
       <xs:element name="z-axis" type="xs:float"/> 
       <xs:element name="w-axis" type="xs:float"/> 
      </xs:all> 
      <xs:attributeGroup ref="origin"/> 
     </xs:complexType> 
    </xs:element> 
    <xs:element name="timestamp" type="xs:long"/> 

    <xs:element name="data"> 
     <xs:complexType> 
      <xs:sequence> 
       <xs:element ref="timestamp" minOccurs="1" maxOccurs="1"/> 

       <xs:choice> 
        <xs:element ref="provider"/> 
        <xs:element ref="sensor"/> 
       </xs:choice> 
      </xs:sequence> 
     </xs:complexType> 
    </xs:element> 

    <!-- definition of main type --> 
    <xs:element name="experience"> 
     <xs:complexType> 
      <xs:sequence> 
       <xs:element ref="data" minOccurs="0" maxOccurs="unbounded"/> 
      </xs:sequence> 
     </xs:complexType> 
    </xs:element> 
</xs:schema> 
+0

首先,谢谢:) 我注意到我忘了定义时间戳,但我已经发布了。这解决了我的问题。 还有一件事,我打算将我的xsd在线,以便任何拥有XML文件或写入XML文件并想验证它的人都可以在线验证XSD。假设它将在“http://mywebsite.com:123/schema/myxsd.xsd”上​​可用。这个链接是否会在我的XML文件中定义,我知道有一个名为“schemaLocation”的属性。 – 2013-05-05 15:48:26

+0

是的,你可以使用xsi:schemaLocation属性在你的XML文件中引用它......它可能并不总是工作,因为并非所有的处理器都会自动跟踪这些位置,特别是如果它们位于远程位置......尽管如此,文件的方式...我个人喜欢的另一种机制是,XSD的targetNamespace实际上可以被解引用到XSD的位置... – 2013-05-05 17:26:02

+0

再次感谢@PetruGardea! ;) – 2013-05-05 22:17:10