[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: chaining schemas
- From: Jeni Tennison <mail@jenitennison.com>
- To: Laura Hatcher <lhatcher@argoneng.com>
- Date: Wed, 08 Aug 2001 18:51:38 +0100
Hi Laura,
> I was hoping that someone would be able to explain something to me.
> I am curious to know how chaining of schemas works. For example if
> you have a schema called schema1.xsd and you include it in
> schema2.xsd, when schema2.xsd gets included into schema3.xsd is
> schema1.xsd accessible to schema3.xsd or do you have to include both
> schema1.xsd and schema2.xsd in schema3.xsd? Also does the namespace
> prefix stay the same through out the includes, or do you have to
> redeclare the namespace with a new namespace prefix.
If you include schema1.xsd into schema2.xsd, and schema2.xsd into
schema3.xsd, then schema3.xsd has access to the definitions in
schema1.xsd. You don't have to include schema1.xsd directly into
schema3.xsd (though I think it won't do any damage if you do).
As far as namespaces go, xs:include does not give you exactly the same
as a straight cut and paste from one document to another. You must
have a namespace declared in a schema if you want to refer to schema
components with that target namespace. You can declare the same
namespace with different prefixes in different schemas and everything
will work fine.
What is important is that the URI of the target namespace of the
included schema is the same as the URI resolved to by the prefix when
you have the reference. A prefix is resolved by looking at the
namespaces in scope in the schema document in which the reference
occurs. So if you have:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.com/foo"
xmlns:ns1="http://www.example.com/foo">
<xs:include schemaLocation="schema1.xsd" />
<xs:element name="foo">
<xs:complexType>
<xs:sequence>
<xs:element ref="ns1:bar" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
then the foo element has a target namespace of
http://www.example.com/foo. The reference to 'ns1:bar' looks for a bar
element with the target namespace of http://www.example.com/foo. The
namespace declaration for ns1 is not available in schema1.xsd. If
schema1.xsd looked as follows:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.com/foo">
<xs:element name="bar">
<xs:complexType>
<xs:sequence>
<xs:element ref="ns1:foo" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
then you would get an error because the ns1 prefix is used in a
reference but is not associated with a namespace. But it is absolutely
fine to declare the http://www.example.com/foo namespace with a
different prefix, for example:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.com/foo"
xmlns:ns2="http://www.example.com/foo">
<xs:element name="bar">
<xs:complexType>
<xs:sequence>
<xs:element ref="ns2:foo" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
The same goes for the use of namespace prefixes in XPaths in identity
constraints - the important thing is the namespace URI that the prefix
you use is associated with in the schema that contains the XPath.
Things are a bit more complicated when you look at Chameleon schemas -
schemas that do not have a target namespace declared themselves, but
adopt the target namespace of the schema that they're included into.
For example, schema1.xsd could be a Chameleon schema:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="bar">
<xs:complexType>
<xs:sequence>
<xs:element ref="foo" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
When it's included into schema2.xsd, which has a target namespace of
http://www.example.com/foo, then it adopts that target namespace. The
bar element is declared as being in that target namespace. *Also* all
the references in schema1.xsd are altered so that if they reference
components that are not in a target namespace (for example, the above
references the foo element in no namespace), then the reference points
to components in the target namespace instead. The above schema is
interpreted exactly as if it had its own target namespace and the
target namespace were declared as the default namespace in the
xs:schema element:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.com/foo"
xmlns="http://www.example.com/foo">
<xs:element name="bar">
<xs:complexType>
<xs:sequence>
<xs:element ref="foo" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Importantly, XPaths don't use the default namespace, so if you have an
XPath in an identity constraint in a Chameleon schema, the identity
constraint will break. For this reason I personally would recommend
you don't use Chameleon schemas.
Cheers,
Jeni
---
Jeni Tennison
http://www.jenitennison.com/