2011-03-24 203 views
1

我遇到問題,試圖針對下面的xml文件測試下面的xsd。我的工具是壞的,還是我的xsd無法以可預測的方式運行?XSD - 驗證時忽略屬性限制

軟件測試:

  • xmllint(使用的libxml版本20707)
  • XML文字編輯1.2.0.6

預期結果:

  • 的test.xml驗證
  • 由於格式錯誤,test-bad.xml驗證失敗在域標籤帳戶屬性

Oberved結果: - 的test.xml驗證 - 測試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> 

回答

3

問題是你不小心名爲 「域」 定義了兩個不同的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> 

由於第一個定義並沒有說明它的屬性什麼,你的樣本文檔中的屬性「帳戶」您domain元素對任何類型都有效。

定義只有一個元素,最好的辦法就是讓element定義你爲complexType,並參閱(另一種方法是將所有的complexType東西第一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

還有兩點意見:(1)你的test.xml是無效的! :)(2)如果你有一個模式,你不應該真的在使用DTD,你只是在重複自己,而DTD遠沒有那麼強大。 – porges 2011-03-25 01:51:36

+1

使用name =「domain」而不是ref =「domain」是一個常見錯誤,除非您仔細測試您的模式,否則通常不會引起注意。撒克遜模式處理器[廣告!]給你一個警告,如果你犯了這個錯誤。 – 2011-03-25 07:36:06

+0

xmllint炸了起來,告訴我test.xml是無效的,沒有這個,我會花更多的時間擺弄這個。@Michael Kay,我聽說這個節目是自切片面包以來最好的。當我想到XML時,我想到了SAXON。 [/廣告!] – 2011-03-25 17:04:15