-->

Why do I have to prefix attributes from imported X

2019-05-26 03:54发布

问题:

I have the following two 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>

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

The instance document looks like this:

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

Now, using Xerces 2.11.0, I have to prefix attributes myAttrib1 and myAttrib2 with ns1 for it to pass validation. At first thought I felt this was not in conformance with the schema definitions (due to the attributeFormDefault="unqualified" in ns1), but giving it a second thought it kind of makes sense. Here's how I understand it: the prefix is necessary because attributes myAttrib1 and myAttrib2 are not defined in the targetNamespace default namespace where they are used, i.e. they're not defined in xmlns="http://www.test.com".

Here's my questions: 1) have I understood the necessity of prefix said attributes correctly, and 2) where in the W3C rec. may I find a passage that describes this behavior? Thanks. :)

UPDATE: I came across the following passage

The final two attributes (elementFormDefault and attributeFormDefault) are a facility provided by W3C XML Schema to control, within a single schema, whether attributes and elements are considered by default to be qualified (in a namespace). This differentiation between qualified and unqualified can be indicated by specifying the default values, as above, but also when defining the elements and attributes, by adding a form attribute of value qualified or unqualified.

It is important to note that only local elements and attributes can be specified as unqualified. All globally defined elements and attributes must always be qualified.

found over at xml.com. Another interesting source is zvon.org. So this really backs up the accepted answer. However, I have yet to see exactly where the (notoriously cryptic) W3C rec. mentions this in detail. After all, they are the governing body in this question.

回答1:

1) Correct. However, the attributeFormDefault and elementFormDefault apply only to locally defined attributes and elements. In other words, those that are not immediate children of schema and redefine, nested within other schema components.

2) Section 3.2.2 shows that ref must be a QName. In general, everywhere in the XSD you see a ref attribute, it'll be of QName type.



回答2:

Top-level element and attribute declarations in a schema are always in the targetNamespace of the schema. The elementFormDefault and attributeFormDefault apply only to anonymous element/attribute declarations that are nested inside a complex type. If your test.xsd schema did not specify elementFormDefault="qualified" then the Child element inside the complex type would not be in a namespace, and the instance document would need to look like

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

Furthermore, attributes that are in a namespace must be prefixed - the default xmlns="..." namespace declaration only applies to elements. Thus

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

is not valid - myAttrib1 and myAttrib2 are not in a namespace.