XML模式xs:xs:sequence中的选择

时间:2013-05-05 12:03:54

标签: xml xsd xsd-validation

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

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

我正在尝试验证以下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:每个无效   cvc-complex-type.1.2.4:element {None}:这里不允许使用的元素(1)in   元素{http://www.w3.org/2001/XMLSchema}:选择,期待   [{http://www.w3.org/2001/XMLSchema}:注释,$ {http://www.w3.org/2001/XMLSchema}:元素,{http://www.w3.org/2001/XMLSchema}:基,{http://www.w3.org/2001/XMLSchema}:选择,{http://www.w3.org/2001/XMLSchema} :序列,{http://www.w3.org/2001/XMLSchema}:任何]:

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

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

如果有人可以帮助我,我会非常感激。

非常感谢提前。

1 个答案:

答案 0 :(得分:3)

您的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:qualifier(这是您提供的错误的要点)

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

但是,通过这些更改,问题现在变成了您的XML,尤其是origin属性。由于您已将属性声明为global,因此必须在XSD的命名空间中进行限定,因此我添加了xmln:tns=...和fixin tns:origin=...

如果您确实不想更改XML,那么您的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">
    <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>