ref for attribute对netbeans下的复杂类型不起作用

时间:2013-11-13 22:47:39

标签: xml netbeans xsd

我正在学习XML和XSD,我遇到了问题。我想使用以下XSD文档验证以下XML文档。因为属性“id”用于两个不同的元素。我想将他的定义与商店和客户的定义分开,然后在其上使用ref。不幸的是,Netbeans似乎忽略了ref属性,或者我做错了,因为当我检查文件store.xml时,我有以下错误:

XML validation started.

Checking file:/Users/toto/NetBeansProjects/Cookbook/src/java/store.xml...
Referenced entity at "file:/Users/strokyl/NetBeansProjects/Cookbook/src/java/store.xsd".
cvc-complex-type.3.2.2: Attribute 'id' is not allowed to appear in element 'client'. [14] 
cvc-complex-type.3.2.2: Attribute 'id' is not allowed to appear in element 'client'. [19] 
cvc-complex-type.3.2.2: Attribute 'id' is not allowed to appear in element 'client'. [24] 
cvc-complex-type.3.2.2: Attribute 'id' is not allowed to appear in element 'product'. [32] 
cvc-complex-type.3.2.2: Attribute 'id' is not allowed to appear in element 'product'. [39] 
cvc-complex-type.3.2.2: Attribute 'id' is not allowed to appear in element 'product'. [46]

当我用客户端和商店的id属性定义替换<xs:attribute ref="id"/>时,xml正确有效!

提前感谢您的宝贵帮助,对不起我的英语(我是法国人)抱歉。

XML文件(store.xml)

<?xml version="1.0" encoding="UTF-8"?>

<!--
    Document   : store.xml.xml
    Created on : 12 novembre 2013, 22:09
    Author     : strokyl
    Description:
        Purpose of the document follows.
-->
<store xmlns="http://etud.insa-toulouse.fr/~duzan/store"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation='http://etud.insa-toulouse.fr/~duzan/store store.xsd'>
    <clients>
        <client id="1">
            <first_name>Luc</first_name>
            <last_name>Duzan</last_name>
            <age>22</age>
        </client>
        <client id="2">
            <first_name>Adrien</first_name>
            <last_name>Gareau</last_name>
            <age>22</age>
        </client>
        <client id="3">
            <first_name>Gilles</first_name>
            <last_name>Roudière</last_name>
            <age>22</age>
        </client>
    </clients>

    <products>
        <product id="1">
            <name>Poster de Maxime Médard</name>
  <!-- You don’t have to use same convention that you use for relational database -->
            <categorie>Poster</categorie>
            <price>10</price>
            <number_in_stock>100</number_in_stock>
        </product>
        <product id="2">
            <name>Poster de Yannick Jauzion</name>
            <categorie>Poster</categorie>
            <price>10</price>
            <number_in_stock>200</number_in_stock>
        </product>

        <product id="3">
            <name>Drapeau du stade toulousain</name>
            <categorie>drapeau</categorie>
            <price>5</price>
            <number_in_stock>500</number_in_stock>
        </product>
    </products>
</store>

xml架构文件(store.xsd)

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://etud.insa-toulouse.fr/~duzan/store"
    xmlns="http://etud.insa-toulouse.fr/~duzan/store"
    elementFormDefault="qualified">

    <xs:element name="store">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="clients"/>
                <xs:element ref="products"/>
                <xs:any/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

<!-- Definition très exposé de clients -->

    <xs:element name="first_name" type="xs:string"/>
    <xs:element name="last_name" type="xs:string"/>

    <xs:element name="age">
        <xs:simpleType>
            <xs:restriction base="xs:integer">
                <xs:minInclusive value="0"/>
                <xs:maxInclusive value="120"/>
            </xs:restriction>
        </xs:simpleType>
    </xs:element>

    <xs:attribute name="id" type="xs:integer"/>

    <xs:complexType name="client_type">
        <xs:sequence>
            <xs:element ref="first_name"/>
            <xs:element ref="last_name"/>
            <xs:element ref="age"/>
        </xs:sequence>
        <xs:attribute ref="id"/>
    </xs:complexType>

    <xs:element name="client" type="client_type"/>

    <xs:complexType name="clients_type">
        <xs:sequence>
            <xs:element ref="client" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>

    <xs:element name="clients" type="clients_type"/>

<!-- Definition très condensé de product à part qu'on réutilise l'attribut id définit plus tôt -->
    <xs:element name="products">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="product" minOccurs="0" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="name" type="xs:string"/>
                            <xs:element name="categorie" type="xs:string"/>
                            <xs:element name="price">
                                <xs:simpleType>
                                    <xs:restriction base="xs:integer">
                                        <xs:minInclusive value="0"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>

                            <xs:element name="number_in_stock">
                                <xs:simpleType>
                                    <xs:restriction base="xs:integer">
                                        <xs:minInclusive value="0"/>
                                        <xs:maxInclusive value="1000"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>

                        </xs:sequence>
                        <xs:attribute ref="id"/>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

2 个答案:

答案 0 :(得分:3)

问题是顶级属性声明采用模式的targetNamespace。因此,验证程序正在查找id命名空间中名为http://etud.insa-toulouse.fr/~duzan/store的属性,但您的文档中包含一个名为id的属性,该属性位于 no 名称空间中(因为默认的xmlns声明不适用于属性)。

要使用现有架构有效,您需要将前缀绑定到命名空间并使用该前缀作为属性

<store xmlns="http://etud.insa-toulouse.fr/~duzan/store"
      xmlns:store="http://etud.insa-toulouse.fr/~duzan/store">
  <!-- ... -->
  <client store:id="1">

相比之下,复杂类型中的 local 属性声明不在命名空间中(除非您在架构上指定attributeFormDefault或在特定声明上指定form)。因此,另一种方法可能是使用属性声明基类型,然后让其他类型扩展它。

<xs:complexType name="identifiedType">
  <xs:attribute name="id" type="xs:integer"/>
</xs:complexType> 

<xs:complexType name="client_type">
  <xs:complexContent>
    <xs:extension base="identifiedType">
      <xs:sequence>
        <xs:element ref="first_name"/>
        <xs:element ref="last_name"/>
        <xs:element ref="age"/>
      </xs:sequence>
    </xs:extension>
  </xs:complexContent>
</xs:complexType>

id属性现在是本地声明而不是全局声明。

答案 1 :(得分:0)

我同意之前的回答,但只是为了简化:

实际上,属性的问题在于,如果要指定重用的全局声明(我的意思是在复杂类型之外),则需要限定xml实例中使用它们的属性。

在您的情况下,您需要在store.xml实例中执行以下操作:

1)为商店声明的名称空间添加前缀,让我们说“ xmlns:store =”http://etud.insa-toulouse.fr/~duzan/store“”:< / p>

<store xmlns="http://etud.insa-toulouse.fr/~duzan/store"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns:store="http://etud.insa-toulouse.fr/~duzan/store"

    xsi:schemaLocation='http://etud.insa-toulouse.fr/~duzan/store store.xsd'>

2)然后您需要限定属性,例如 store:id

<clients>
    <client store:id="1">
        <first_name>Luc</first_name>
        <last_name>Duzan</last_name>
        <age>22</age>
    </client>

我的建议:

  • 为什么要使用属性? SOA中的实践是在可能的情况下使用元素(当然不是每个人都认为相同......)
  • 如果您确实需要它们,那么只使用属性的本地声明(在复杂类型中)以避免在实例中对名称空间进行详细说明。