为什么我必须为导入的XSD添加前缀属性?

时间:2012-11-06 12:13:05

标签: xml xsd xsd-validation

我有以下两个XSDS,test.xsd

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"    
  xmlns:xsd="http://www.w3.org/2001/XMLSchema.xsd" 
  xmlns:ns1="http://www.test.com/ns1"     
  targetNamespace="http://www.test.com" 
  elementFormDefault="qualified"
  attributeFormDefault="unqualified">
    <import namespace="http://www.test.com/ns1" schemaLocation="test1.xsd"/>
    <element name="Root">
        <complexType>
            <sequence>
                <element name="Child" type="string"/>
            </sequence>
            <attribute ref="ns1:myAttrib1" use="required"/>
            <attribute ref="ns1:myAttrib2" use="required"/>
        </complexType>
    </element>
</schema>

和test1.xsd

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" 
  xmlns:xsd="http://www.w3.org/2001/XMLSchema.xsd" 
  xmlns:ns1="http://www.test.com/ns1" 
  targetNamespace="http://www.test.com/ns1" 
  elementFormDefault="qualified" attributeFormDefault="unqualified">
    <attribute name="myAttrib1" type="string"/>
    <attribute name="myAttrib2" type="string"/>
</schema>

实例文档如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<Root xmlns="http://www.test.com" xmlns:ns1="http://www.test.com/ns1" 
  ns1:myAttrib1="1" ns1:myAttrib2="2">
    <Child>Child 1</Child>
</Root>

现在,使用Xerces 2.11.0,我必须将属性myAttrib1myAttrib2加上ns1前缀,以便通过验证。起初我以为我觉得这不符合模式定义(由于attributeFormDefault="unqualified"中的ns1),但给它第二个想法是有道理的。以下是我理解它的方法:前缀是必要的,因为属性myAttrib1myAttrib2未在 targetNamespace 默认命名空间中定义,使用它们,即它们'未在xmlns="http://www.test.com"中定义。

这是我的问题:1)我是否理解了前缀所述属性的必要性,以及2)在W3C rec中的位置。我可以找一个描述这种行为的段落吗?谢谢。 :)

更新:我遇到了以下段落

  

最后两个属性(elementFormDefault和attributeFormDefault)   是由W3C XML Schema提供的一个工具,用于控制单个内容   架构,默认情况下是否考虑属性和元素   合格(在命名空间中)。这种区分合格   可以通过指定默认值来表示不合格,如   上面,也是在定义元素和属性时,通过添加一个   价值合格或不合格的格式属性。

     

重要的是要注意只有本地元素和属性   指定为不合格。所有全局定义的元素和属性   必须始终合格。

xml.com找到了。另一个有趣的来源是zvon.org。所以这真的支持了接受的答案。但是,我还没有看到(众所周知的神秘)W3C rec的确切位置。详细提到这一点。毕竟,他们是这个问题的管理机构。

2 个答案:

答案 0 :(得分:2)

模式中的顶级元素和属性声明始终位于模式的targetNamespace中。 elementFormDefaultattributeFormDefault仅适用于嵌套在复杂类型中的匿名元素/属性声明。如果您的test.xsd架构未指定elementFormDefault="qualified",则复杂类型中的Child元素将不在命名空间中,并且实例文档需要看起来像

<?xml version="1.0" encoding="UTF-8"?>
<ns:Root xmlns:ns="http://www.test.com" xmlns:ns1="http://www.test.com/ns1" 
  ns1:myAttrib1="1" ns1:myAttrib2="2">
    <Child>Child 1</Child>
</Root>

此外,名称空间中的属性必须作为前缀 - 默认的xmlns="..."名称空间声明仅适用于元素。因此

<?xml version="1.0" encoding="UTF-8"?>
<ns:Root xmlns="http://www.test.com/nl1" xmlns:ns="http://www.test.com" 
  myAttrib1="1" myAttrib2="2">
    <ns:Child>Child 1</ns:Child>
</ns:Root>

有效 - myAttrib1和myAttrib2不在命名空间中。

答案 1 :(得分:1)

1)正确。但是,attributeFormDefaultelementFormDefault仅适用于本地定义的属性和元素。换句话说,那些不是架构重新定义的直接子项的人,嵌套在其他架构组件中。

2)Section 3.2。2表明ref必须是QName。通常,在XSD中的任何地方都会看到ref属性,它将是QName类型。