Referencing additional schemas during parsing

In some advanced parsing situations, you might need to reference additional schemas as well as your main schema during parsing.

To specify additional schemas, set the XmlParseOptions.AdditionalSchemas to a specific SchemaAccess object. This SchemaAccess object represents the XSD. To access an additional schema from an XSD, use the syntax:

package_for_the_schema.util.SchemaAccess

To see how and why you would specify additional schemas, suppose you have the following two schemas:

ImportXSD1.xsd:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:ImportXSD1"
        xmlns:ImportXSD1="urn:ImportXSD1">
  <xsd:element name="ElementFromSchema1" type="ImportXSD1:TypeFromSchema1"/>
  <xsd:complexType name="TypeFromSchema1"/>
</xsd:schema>

ImportXSD2.xsd:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:ImportXSD2"
        xmlns:ImportXSD1="urn:ImportXSD1" xmlns:ImportXSD2="urn:ImportXSD2" 
        elementFormDefault="qualified">
  <xsd:import schemaLocation="ImportXSD1.xsd" namespace="urn:ImportXSD1"/>
  <xsd:complexType name="TypeFromSchema2"> 
    <xsd:complexContent>  <!-- the TypeFromSchema2 type extends the TypeFromSchema1 type! --> 
      <xsd:extension base="ImportXSD1:TypeFromSchema1"/>
    </xsd:complexContent>
  </xsd:complexType>
</xsd:schema>

Notice that the ImportXSD2 XSD extends a type that the ImportXSD1 defines. This definition is analogous to saying the ImportXSD2 type called TypeFromSchema2 is a subclass of the ImportXSD1 type called TypeFromSchema1.

The following code fails by throwing an exception because the ImportXSD1 references the schema type ImportXSD2:TypeFromSchema2 and Gosu cannot find that type in the current schema.

var schema2 = docexamples.gosu.xml.importxsd2.util.SchemaAccess

var xsdtext = "<ElementFromSchema1 xmlns=\"urn:ImportXSD1\" xmlns:ImportXSD2=\"urn:ImportXSD2\"" +
  " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"ImportXSD2:TypeFromSchema2\"/>"

// Parse an element defined in the the first schema, but pass an extension to that
// that type that the second schema defines. THIS FAILS without using the AdditionalSchemas feature.
var element = ElementFromSchema1.parse(xsdtext)

The ImportXSD1 XSD type cannot locate the schema called ImportXSD2 even though the specification extends a type that ImportXSD2 defines.

To provide access to the additional schema, set the AdditionalSchemas property of the XmlParseOptions object to a list containing one or more SchemaAccess objects. The following code parses XML successfully:

var schema2 = docexamples.gosu.xml.importxsd2.util.SchemaAccess
var options = new gw.xml.XmlParseOptions() { :AdditionalSchemas = { schema2 } }

var xsdtext = "<ElementFromSchema1 xmlns=\"urn:ImportXSD1\" xmlns:ImportXSD2=\"urn:ImportXSD2\"" +
  " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"ImportXSD2:TypeFromSchema2\"/>"

// Parse an element defined in the the first schema, but pass an extension to that
// type that the second schema defines by using the XmlParseOptions. 
var element = ElementFromSchema1.parse(xsdtext, options)

You can remap an external namespace or XSD URL to a local XSD using the gwxmlmodule.xml file.

See also