开发者

XSD - attribute restriction ignored when validating

I am having issues trying to test the below xsd against the below xml files. Are my tools bad, or is my xsd not functioning in a predictable way?

Software tested:

  • xmllint (using libxml version 20707)
  • XML Copy Editor 1.2.0.6

Expected results:

  • test.xml validates
  • test-bad.xml fails validation due to malformed account attribute in domain tag

Oberved results: - test.xml validates - test-bad.xml validates

test.xml

<?xml version="1.0" ?>
<!DOCTYPE configuration S开发者_C百科YSTEM "configuration.dtd">
<configuration  timestamp="2011-03-23T20:16:57.222" version="2.2" xmlns="http://www.example.com/api/2.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.com/api/2.2 configuration.xsd">
    <domain account="4af17ss66f-c841-4b97-a94a-edd7a012176" >
    </domain>
</configuration>

test-bad.xml

<?xml version="1.0" ?>
<!DOCTYPE configuration SYSTEM "configuration.dtd">
<configuration  timestamp="2011-03-23T20:16:57.222" version="2.2" xmlns="http://www.example.com/api/2.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.com/api/2.2 configuration.xsd">
    <domain account="totally invalid account" >
    </domain>
</configuration>

configuration.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.example.com/api/2.2" elementFormDefault="qualified" version="1.0" xml:lang="EN" targetNamespace="http://www.example.com/api/2.2">
  <xs:element name="configuration">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="domain"/>
      </xs:sequence>
      <xs:attribute name="timestamp" type="xs:normalizedString" use="optional"/>
      <xs:attribute name="version" type="xs:token" fixed="2.2"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="domain">
    <xs:complexType>
      <xs:sequence>
        <xs:any minOccurs="0"/>
      </xs:sequence>
      <xs:attribute name="account" type="uid" use="required">
        </xs:attribute>
    </xs:complexType>
  </xs:element>
  <xs:simpleType name="uid">
    <xs:restriction base="xs:string">
      <xs:length value="36"/>
      <xs:pattern value="[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}"/>
    </xs:restriction>
  </xs:simpleType>
</xs:schema>

configuration.dtd

<!ELEMENT configuration (domain)>
<!ATTLIST configuration
            timestamp           CDATA #IMPLIED
            version             CDATA #FIXED "2.2"
            xmlns               CDATA #IMPLIED
            xmlns:xsi           CDATA #IMPLIED
            xsi:schemaLocation  CDATA #IMPLIED>
<!ELEMENT domain ANY>
<!ATTLIST domain account CDATA #IMPLIED>


The problem is you've accidentally defined two different elements with the name "domain".

This defines one, which can occur only inside configuration:

    <xs:element name="domain"/>

And this defines the other, which can only occur as a root element (you can see this if you remove the configuration element and have domain as the root - it won't validate anymore):

<xs:element name="domain">
  <xs:complexType>
    <xs:sequence>
      <xs:any minOccurs="0"/>
    </xs:sequence>
    <xs:attribute name="account" type="uid" use="required">
      </xs:attribute>
  </xs:complexType>
</xs:element>

Since the first definition doesn't say anything about its attributes, in your sample document the attribute "account" on your domain element is valid with any type.

To define only one element, the best way is to make the element definition you have into a complexType, and refer to that (the other alternative is to move all the complexType stuff inside the first domain deinfition):

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.example.com/api/2.2" elementFormDefault="qualified" version="1.0" xml:lang="EN" targetNamespace="http://www.example.com/api/2.2">
  <xs:element name="configuration">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="domain" type="domain"/> <!-- changed here -->
      </xs:sequence>
      <xs:attribute name="timestamp" type="xs:normalizedString" use="optional"/>
      <xs:attribute name="version" type="xs:token" fixed="2.2"/>
    </xs:complexType>
  </xs:element>

  <xs:complexType name="domain"> <!-- and here -->
    <xs:sequence>
      <xs:any minOccurs="0"/>
    </xs:sequence>
    <xs:attribute name="account" type="uid" use="required">
      </xs:attribute>
  </xs:complexType>

  <xs:simpleType name="uid">
    <xs:restriction base="xs:string">
      <xs:length value="36"/>
      <xs:pattern value="[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}"/>
    </xs:restriction>
  </xs:simpleType>
</xs:schema>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜