- From: Mark Feblowitz <mfeblowitz@frictionless.com>
- Date: Wed, 19 Dec 2001 15:28:25 -0500
- To: "Xmlschema-Dev (E-mail)" <xmlschema-dev@w3.org>
On many occasions, I have found the need to define a structure in one namespace and refine it and extend it in another. This always results in me getting wrapped around the axle, going round and round over how to represent all that needs representing. I suspect that this is a problem shared by many. I've come up with a workable but awkward approach, but I'd like to know if there's a better way. The two major difficulties I encounter are 1) keeping the refinement and extension appropriately separate and 2) keeping namespace prefixing in the instance document simple and manageable. I'll demonstrate in a somewhat contrived example. Say I have a complex type DocumentType defined in namespace ns1. It defines the element Header of type HeaderType and Line of type LineType: <xs:schema targetNamespace="ns1" xmlns="ns1" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:element name="Document" type="DocumentType"/> <xs:complexType name="DocumentType"> <xs:sequence> <xs:element name="Header" type="HeaderType"/> <xs:element name="Line" type="LineType" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> <xs:complexType name="HeaderType"> <xs:sequence> <xs:element name="CreationDate" type="xs:date"/> </xs:sequence> </xs:complexType> <xs:complexType name="LineType"> <xs:sequence> <xs:element name="LineNumber" type="xs:positiveInteger"/> </xs:sequence> </xs:complexType> </xs:schema> Fairly simple. Now, in namespace ns2, I'd like to build an extended DocumentType, based on ns1:DocumentType, to add a Footer element: <xs:schema targetNamespace="ns2" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="ns2" xmlns:ns1="ns1" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:import namespace="ns1" schemaLocation="RefineExtend-NS1.xsd"/> <xs:element name="Document" type="DocumentType"/> <xs:complexType name="DocumentType"> <xs:complexContent> <xs:extension base="ns1:DocumentType"> <xs:sequence> <xs:element name="Footer"/> </xs:sequence> </xs:extension> </xs:complexContent> </xs:complexType> </xs:schema> Also simple. I'd also like to extend ns1:HeaderType to add, e.g., a LastModifiedDate: ... <xs:complexType name="HeaderType"> <xs:complexContent> <xs:extension base="ns1:HeaderType"> <xs:sequence> <xs:element name="LastModifiedDate" type="xs:date"/> </xs:sequence> </xs:extension> </xs:complexContent> </xs:complexType> ... The trouble arises when I want to have ns2:DocumentType use the extended HeaderType. In order to rebind the Header element in ns2:DocumentType to be ns2:HeaderType, I must define ns2:DocumentType to restrict ns1:DocumentType: <xs:schema targetNamespace="ns2" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="ns2" xmlns:ns1="ns1" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:import namespace="ns1" schemaLocation="RefineExtend-NS1.xsd"/> <xs:element name="Document" type="DocumentType"/> <xs:complexType name="DocumentType"> <xs:complexContent> <xs:restriction base="ns1:DocumentType"> <xs:sequence> <xs:element name="Header" type="HeaderType"/> <xs:element name="Line" type="ns1:LineType" maxOccurs="unbounded"/> </xs:sequence> </xs:restriction> </xs:complexContent> </xs:complexType> <xs:complexType name="HeaderType"> <xs:complexContent> <xs:extension base="ns1:HeaderType"> <xs:sequence> <xs:element name="LastModifiedDate" type="xs:date"/> </xs:sequence> </xs:extension> </xs:complexContent> </xs:complexType> </xs:schema> In doing so I have lost the ability to extend ns2:DocumentType to include the footer element. If I add the footer element footer into the restriction sequence, I have violated the rules of restriction. How I've handled it, in an unpretty way, is to separate the extension step and the restriction step into two levels of hierarchy. ns2:DocumentBaseType restricts ns1:DocumentType so that I can bind the element Header to type ns2:HeaderType. ns2:DocumentType then extends DocumentBaseType to add the Footer element: <xs:schema targetNamespace="ns2" xmlns:ns1="ns1" xmlns="ns2" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:import namespace="ns1" schemaLocation="RefineExtend-NS1.xsd"/> <xs:element name="Document" type="DocumentType"/> <xs:complexType name="DocumentBaseType"> <xs:complexContent> <xs:restriction base="ns1:DocumentType"> <xs:sequence> <xs:element name="Header" type="HeaderType"/> <xs:element name="Line" type="ns1:LineType" maxOccurs="unbounded"/> </xs:sequence> </xs:restriction> </xs:complexContent> </xs:complexType> <xs:complexType name="DocumentType"> <xs:complexContent> <xs:extension base="DocumentBaseType"> <xs:sequence> <xs:element name="Footer"/> </xs:sequence> </xs:extension> </xs:complexContent> </xs:complexType> <xs:complexType name="HeaderType"> <xs:complexContent> <xs:extension base="ns1:HeaderType"> <xs:sequence> <xs:element name="LastModifiedDate" type="xs:date"/> </xs:sequence> </xs:extension> </xs:complexContent> </xs:complexType> </xs:schema> Messy, but workable. The result is an instance document with root element Document as defined in ns2: <Document xmlns="ns2" xmlns:ns1="ns1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="ns2 RefineExtend-NS2-3.xsd"> <Header> <ns1:CreationDate>1967-08-13</ns1:CreationDate> <LastModifiedDate>1967-08-13</LastModifiedDate> </Header> <Line> <ns1:LineNumber>2</ns1:LineNumber> </Line> <Footer>Text</Footer> </Document> Since most of the content has been defined via restriction, the only namespace prefixes required are for the elements or types that are fully defined in ns1. It can be confusing for the user of the ns2 xsd to figure out the correct namespace prefixing of elements in the instance documents, though, especially when the content originated in ns1 and only "migrates" to ns2 as the result of a restriction. It gets even more confusing when this kind of refinement/extension cascades down more levels. My questions are 1) Am I doing this right? and 2) Are there better ways to achieve what I need to? Mark Feblowitz XML Architect Frictionless Commerce Incorporated 400 Technology Square, 9th floor Cambridge, MA 02139 (617) 715-7231 mfeblowitz@frictionless.com
Received on Wednesday, 19 December 2001 15:29:01 UTC