XSD - ограничение атрибута игнорируется при проверке - PullRequest
1 голос
/ 25 марта 2011

У меня возникают проблемы при попытке проверить приведенный ниже xsd на приведенных ниже xml-файлах. Мои инструменты плохие или мой xsd не работает предсказуемо?

Программное обеспечение протестировано:

  • xmllint (с использованием libxml версии 20707)
  • XML Copy Editor 1.2.0.6

Ожидаемые результаты:

  • test.xml проверяет
  • test-bad.xml не проходит проверку из-за неверно сформированного атрибута учетной записи в теге домена

Результаты Oberved: - test.xml проверяет - test-bad.xml проверяет

test.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="4af17ss66f-c841-4b97-a94a-edd7a012176" >
    </domain>
</configuration>

тест-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>

1 Ответ

3 голосов
/ 25 марта 2011

Проблема в том, что вы случайно определили два разных element с именем "домен".

Это определяет один, который может встречаться только внутри configuration:

    <xs:element name="domain"/>

И это определяет другой, который может появляться только как корневой элемент (это можно увидеть, если вы удалите элемент configuration и у вас будет domain в качестве корневого элемента - он больше не будет проверяться):

<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>

Поскольку первое определение ничего не говорит о его атрибутах, в вашем примере документа атрибут "account" в вашем элементе domain действителен для любого типа.

Чтобы определить только один элементлучший способ состоит в том, чтобы превратить имеющееся у вас element определение в complexType и сослаться на него (другая альтернатива - переместить все элементы complexType внутри первого domain деинфекции):

<?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>
...