约束id属性在xsd文档中是唯一的

时间:2014-01-21 08:52:41

标签: xml xsd

我有这个xsd

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/XXX"
    xmlns:tns="http://www.example.org/XXX" elementFormDefault="qualified">

    <simpleType name="Name">
        <restriction base="string"></restriction>
    </simpleType>

    <simpleType name="Phone">
        <restriction base="string">
            <pattern value="\d+"></pattern>
        </restriction>
    </simpleType>

    <simpleType name="Id">
        <restriction base="string">
            <pattern value="[a-zA-Z]\w+"></pattern>
        </restriction>
    </simpleType>

    <complexType name="User">
        <attribute name="Id" type="tns:Id" use="required"></attribute>
        <attribute name="Name" type="tns:Name" use="required"></attribute>
        <attribute name="Phone" type="tns:Phone" use="required"></attribute>
    </complexType>

    <complexType name="ROOT">
        <sequence>
            <element name="User" type="tns:User" minOccurs="0" maxOccurs="unbounded">
                <key name="idUser">
                    <selector xpath="User"></selector>
                    <field xpath="@Id"></field>
                </key>
            </element>
        </sequence>
    </complexType>
    <element name="root" type="tns:ROOT">
    </element>
</schema>

并且我想限制字段ID,使其在文档内部唯一,而不是在树的分支内部。显然在这个例子中没有任何变化,但我的想法是我可以在根元素内部有一系列服务器,并且对于每个服务器,用户必须是唯一的,但同时可以存在两个具有相同Id的用户,如果他们不存在属于同一台服务器。 例如,如果只有s1和s2这个文档是有效的,但它无效,因为s3有两个内部具有相同id的用户。

<?xml version="1.0" encoding="UTF-8"?>
<tns:XXX xmlns:tns="http://www.example.org/XXX" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org/XXX schema.xsd ">  
  <tns:Server Id="s1">
    <tns:User Id="u1" Name="Name" Phone="12" />
    <tns:User Id="u2" Name="Name1" Phone="87654" />
  </tns:Server Id="s2">
  <tns:Server Id="a2">
    <tns:User Id="u2" Name="Name" Phone="12" />
    <tns:User Id="u4" Name="Name1" Phone="87654" />
  </tns:Server>
  <tns:Server Id="s3">
    <tns:User Id="u2" Name="Name" Phone="12" />
    <tns:User Id="u2" Name="Name1" Phone="87654" />
  </tns:Server>
</tns:ACSInfo>

我尝试使用密钥标签但是如果我尝试验证这个xml它会通过,我希望它不能!

<?xml version="1.0" encoding="UTF-8"?>
<tns:XXX xmlns:tns="http://www.example.org/XXX" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org/XXX schema.xsd ">
  <tns:User Id="a1" Name="Name" Phone="12" />
  <tns:User Id="a1" Name="Name1" Phone="87654" />
</tns:XXX>

1 个答案:

答案 0 :(得分:1)

您的架构不正确以强制执行唯一性。你应该使用xsd:unique。范围也应该是<root/>而不是<User/>

试试这个:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="http://www.example.org/XXX"
           elementFormDefault="qualified"
           xmlns="http://www.example.org/XXX"
           xmlns:tns="http://www.example.org/XXX"
           xmlns:xs="http://www.w3.org/2001/XMLSchema" >

  <xs:simpleType name="Name">
    <xs:restriction base="xs:string" />
  </xs:simpleType>

  <xs:simpleType name="Phone">
    <xs:restriction base="xs:string">
      <xs:pattern value="\d+" />
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="Id">
    <xs:restriction base="xs:string">
      <xs:pattern value="[a-zA-Z]\w+" />
    </xs:restriction>
  </xs:simpleType>

  <xs:complexType name="User">
    <xs:attribute name="Id" type="Id" use="required" />
    <xs:attribute name="Name" type="Name" use="required" />
    <xs:attribute name="Phone" type="Phone" use="required" />
  </xs:complexType>

  <xs:element name="root">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="User" type="User" 
                    minOccurs="0" maxOccurs="unbounded" />
      </xs:sequence>
    </xs:complexType>
    <xs:unique name="idUser">
      <xs:selector xpath="tns:User" />
      <xs:field xpath="@Id" />
    </xs:unique>
  </xs:element>
</xs:schema>

<强>更新

要更改唯一性的范围,只需将其向上移动一级:

 <xs:element name="root">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Server" minOccurs="0" maxOccurs="unbounded">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="User" type="User" minOccurs="0" maxOccurs="unbounded" />
            </xs:sequence>
          </xs:complexType>
          <xs:unique name="idUser">
            <xs:selector xpath="tns:User" />
            <xs:field xpath="@Id" />
          </xs:unique>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

这将允许您重复使用用户ID,但不能在<Server/>