Whitepapers
How Many XSDs To Validate an XML
Send Feedback

Glossary Item Box

It is a common task to infer from an XML a matching XSD. When performed automatically, it may happen that in many areas the generated content falls short of expectations; and when it does, it may also have to do with the number of generated XSD files.

This sets out to describe the rules that provide the minimum number of XSD files needed to describe a given XML; the main focus is on the subject that fools the tools (and people) most of the time: an XSD's target namespace and the qualification of local elements and attributes.

The Rules

  1. If there are no namespaces involved, then one XSD is all that's needed.
  2. If the root element is qualified, then the minimum number of XSD files equals the number of distinct namespaces which qualify any of the other elements and attributes.
  3. If the root element is unqualified, the minimum number of XSD files is that of distinct namespaces which qualify any of the other elements and attributes, plus one.

 

Scenario: Unqualified Root Element

The only case when unqualified content demands its own XSD is when the root element is unqualified.

Below is a simple XML, showing an unqualified root element.

Sample1.xml Copy Code
<root>
    <inner xmlns="urn:test:1"></inner>
</root>

Let's look at the automatically generated XSDs for Sample1 xml; we are illustrating using .NET built in support.

In QTAssistant, the quickest way to get "matching" XSD(s) is to invoke the Create Schema command. 

The first XSD (Root1) has no target namespace; it describes the root tag.

Root1.xsd Copy Code
<xsd:schema xmlns:ns1="urn:test:1" attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:import schemaLocation="Inner1.xsd" namespace="urn:test:1" />
  <xsd:element name="root">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element xmlns:q1="urn:test:1" ref="q1:inner" />
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

 The second XSD (Inner1) has a target namespace that describes the qualified {urn:test:1}inner element.

Inner1.xsd Copy Code
<xsd:schema xmlns="urn:test:1" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="urn:test:1" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="inner" />
</xsd:schema>

 

Scenario: Qualified Root Element

What if we swap namespaces between elements?

Sample2.xml Copy Code
<root xmlns="urn:test:1">
    <inner xmlns=""></inner>
</root>

Let's generate again and have a look at the XSDs; The first XSD (Root2) has a target namespace that matches the root tag.

Root2.xsd Copy Code
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="urn:test:1" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:import schemaLocation="Inner2.xsd" />
  <xsd:element name="root">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element ref="inner" />
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

The second XSD (Inner2) has no target namespace and describes the unqualified inner element. 

Inner2.xsd Copy Code
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <xsd:element name="inner" />
</xsd:schema>

However, Rule #2 is not verified. The reason is the referencing of the inner element, which by definition requires a global definition; being an unqualified element, it requires another XSD. 

 

The workaround that gives an XSD that validates Rule #2 is shown below; it instead uses an local element definition for the inner element (thus getting away from the "needy" ref approach). To unqualify, it relies on form="unqualified".

Root3.xsd Copy Code
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="urn:test:1" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="root">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="inner" form="unqualified" />
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>