Page 1 of 1

Qualifying global elements

Posted: Tue Oct 24, 2017 5:17 pm
by Iwicka
Hello,

I have a question about qualifying elements in the instance that are globally declared in the schema.

I have the two following schemas:

Code: Select all

<xs:schema xmlns:L="HKJ" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="HKJ" elementFormDefault="unqualified" attributeFormDefault="unqualified">
   <xs:element name="Root">
      <xs:complexType>
         <xs:sequence>
            <xs:element name="A">
               <xs:complexType>
                  <xs:sequence>
                     <xs:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
                  </xs:sequence>
               </xs:complexType>
            </xs:element>
            <xs:element name="B" type="xs:string"/>
         </xs:sequence>
      </xs:complexType>
   </xs:element>
</xs:schema>


and

Code: Select all

<xs:schema xmlns:G="XYZ" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="XYZ" elementFormDefault="unqualified" attributeFormDefault="unqualified">
   <xs:element name="C">
      <xs:complexType>
         <xs:sequence>
            <xs:element name="D"/>
            <xs:element name="E"/>
         </xs:sequence>
      </xs:complexType>
   </xs:element>
</xs:schema>

When I create an instance based on Main.xsd schema, using element C as a child of element A (replacing the ##any placeholder), it is valid in Oxygen (and other tools for that matter) with or without the namespace prefix used for element C:

Code: Select all

<L:Root xmlns:L="HKJ" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="HKJ Main.xsd">
   <A>
      <G:C xmlns:G="XYZ" xsi:schemaLocation="XYZ Component.xsd"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
         <D/>
         <E/>
      </G:C>
   </A>
   <B>String</B>
</L:Root>


And this is valid as well:

Code: Select all

<L:Root xmlns:L="HKJ" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="HKJ Main.xsd">
   <A>
      <C xmlns:G="XYZ" xsi:schemaLocation="XYZ Component.xsd"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
         <D/>
         <E/>
      </C>
   </A>
   <B>String</B>
</L:Root>


Can you explain why? I always knew that if an element is declared globally in the schema and the namespace is explicit, it has to be qualified in the instance. Why then the <C> without namespace prefix is valid? I’m clearly missing something here.
Thank you for any help,

Ewa

Re: Qualifying global elements

Posted: Fri Oct 27, 2017 5:11 pm
by adrian
Hello,
Iwicka wrote: I always knew that if an element is declared globally in the schema and the namespace is explicit, it has to be qualified in the instance. Why then the <C> without namespace prefix is valid? I’m clearly missing something here.

That is correct, globally declared elements are always qualified (in the target namespace).

The problem is that the schema allows any element from any namespace within the A element, even if a schema is not available for it. This happens because of processContents="lax":

Code: Select all

    <xs:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>

About processContents wrote:Specifies the validation constraint to be applied on the content that matched the wildcard. Possible values are
* skip - that means no validation
* lax - that means validation will be performed if a schema is available
* strict - that means validation is required
The default is strict.

e.g. This "validates perfectly" and doesn't have anything to do with the Component schema. So, "anything goes":

Code: Select all

<L:Root xmlns:L="HKJ" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="HKJ Main.xsd">
  <A>
    <ANYTHING>
      <I/>
      <WANT/>
    </ANYTHING>
  </A>
  <B>String</B>
</L:Root>

This can be easily fixed by making processContents="strict". You'll then see the results you are expecting, instance 1 validates and instance 2 fails.

Regards,
Adrian