2011-03-24 124 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