The Use of Profiling in XML Documents   Table of contents   Indexes   Data Models as an XML Schema Development Method

Buck, Lee
Extensibility, Inc.
 
Lee Buck
 Chief Technology Officer
Extensibility, Inc.
 Biography
 Lee Buck is the co-founder and Chief Technology Officer of Extensibility, Inc. a leading provider of XML tools. Lee is a recognized authority on XML and schema and serves on a number of technical committees including the W3C’s XML Schema Working Group. Prior to Extensibility, Lee headed up Software Designs Unlimited, a commercial software developer serving clients such as National Geographic Society, Simon & Schuster and Charles Schwab. Lee is also the author of an awarding winning RAD tool developed in collaboration with, and distributed by Apple Computer.
 

Introduction

 This document is intended to be of use to anyone confronting modeling issues in XML. It assumes a fairly intimate understanding of the concepts and syntax of XML schemas particularly DTDs. It also represents the approach taken by XML Authority in providing automated schema creation from relational data sources.
 

Motivation

 XML provides a compelling environment for the integration of disparate forms of data in a platform independent manner. Developers from a wide array of backgrounds are struggling to express concepts familiar to them in the syntax of XML. While robust information modeling concepts are being developed in the w3c schema working group, the reality is that there is a significant audience of early adopters that need guidance now. This document is an attempt to leverage existing tools (e.g. validating parsers, browsers) and standards to address some of these needs in the context of relational databases.
 This document is intended to be of use to anyone confronting modeling issues in XML. It assumes a fairly intimate understanding of the concepts and syntax of XML schemas particularly DTDs. It also represents the approach taken by XML Authority in providing automated schema creation from relational data sources.
 

Modeling Spectrum

 When mapping information from traditional (e.g. relational, object-oriented) data models to XML, there is no single right answer. Instead there is a spectrum of potential approaches. At one end of the spectrum is the custom mapping of individual pieces of information from the database into a "pre-ordained" schema (e.g. an industry standard interchange format). This approach implies significant custom code to perform the mappings between the two loosely coupled schema (that of the database and that of the pre-ordained schema).
 At the other end of the spectrum is a "data-dump" of the entire contents of a database with the intention of re-constituting the database with all of its relationships and data intact. This approach tends to yield a mechanical mapping onto a generic metadata schema. XMI, promulgated by the OMG, is one such generic metadata schema. In this approach, the schema is not about the business; it's about the metadata concepts themselves.
 Both ends of spectrum are common and useful ways of modeling relational data. Both have their drawbacks: the need for substantial custom code, and the obscuring of the business concepts. In this document we set forth an approach that lies between these two extremes and apply it to relational data bases. It provides mechanical mappings of key database structure concepts while retaining the notion that the schema should be about the business information. This approach has the merit of yielding straightforwardly understandable schemas which are congruent with existing data structures and which leverage XML concepts such as ID/IDREF. This approach is not guaranteed to provide 100% fidelity when round-tripping data from a RDBMS to XML back to an RDBMS but whenever possible, we identify such limitations and potential workarounds.
 

The Example

 Let's use a simple example to work in the concrete. The following is an employee database with three tables. EMPLOYEE stores personal information and a summary of the term of the relationship. PERF_REVIEW stores performance reviews given to the employee. COMP_CHANGE stores changes to compensation resulting (usually but not always) from a performance review.
 
TABLE EMPLOYEE
 
NUM LONGINT PRIMARY KEY
 
FNAME STRING 32
 
LNAME STRING 32
 
HIRE_DATE DATE
 
TERM_DATE DATE MAY BE NULL
 
TABLE PERF_REVIEW
 
EMP_NUM LONGINT PRIMARY KEY FOREIGN KEY
 
REVIEW_DATE DATE PRIMARY KEY
 
REVIEW TEXT
 
TABLE COMP_CHANGE
 
EMP_NUM LONGINT FOREIGN KEY
 
REVIEW_DATE DATE MAY BE NULL
 
EFF_DATE DATE
 
SALARY INT
 At its simplest, a XML document of information drawn from this example might look like this:
 
<EMPLOYEE
 
NUM = '2361'
 
FNAME = 'Wilbert'
 
LNAME = 'Winston'
 
HIRE_DATE = '4/4/88'>
 
</EMPLOYEE>
 Notice we have an element named after the table that corresponds to a row of data with attributes containing the values for each of the columns. (We could equally have had sub-elements containing the column data.) While a good start, there are crucial improvements we can make to the model:
 
  •  Support for datatypes information
  •  Retention of key relationships
  •  Leveraging of XML's ID/IDREF facilities
 To make these improvements we'll need to capture additional information in the schema using techniques outlined next.
 

Extending the DTD

 The DTD syntax is very efficient in expressing a certain set of constraints on conforming documents. However, it knows nothing about concepts such as key relationships. We'll extend the DTD to capture such additional information for the Element Types and Attribute Types that we define in our schema. We'll use fixed attributes to accomplish this because the value of fixed attributes is unchangeable in individual instances of an element so they can be thought of as properties of the element type itself rather than of an instance. So:
 
  1.  For element types we associate the property by adding a fixed nmtoken attribute whose name is preceded by an e-. The value of this attribute is the value of the property. For example, to associate 'red' as the value of the 'color' property for the element type 'quark' we would define an attribute e-color whose fixed value was 'red'.
  2.  For attribute types we associate the property by adding an attribute type name / property value pair to a fixed nmtokens attribute whose name is the property name preceded by an a-. For example, to associate 'red' as the value of the 'color' property for a particular attribute type named 'bark' we would define an attribute a-color whose fixed value was 'blue' contained the 'bark blue' (as well potentially other pairs (e.g. bite pink) for the color property).
 
<!ATTLIST quark bark CDATA #IMPLIED
 
bite CDATA #IMPLIED
 
e-color NMTOKEN #FIXED 'red'
 
a-color NMTOKENS #FIXED 'bark blue bite pink'
 
>
 For our purposes we'll need four such properties:
 
  •  dtype - The datatype for the element or attribute type. This is used to more fully specify the allowed values for an element of type PCDATA or an attribute of type CDATA. For a discussion of the use and meaning of the property, see Modeling Datatypes below.
  •  dsize - The storage size and/or precision for the datatype. For a discussion of the use and meaning of the property, see Modeling Datatypes below.
  •  pkey - The name of the attribute or element type(s) which corresponds to the primary key column. In the case of aggregate keys, this is a space-delimited list. This is used only on the element type corresponding to a table. For a discussion of the use and meaning of the property, see Modeling Relationships below.
  •  Fkey - A reference to the attribute or element type which represents the column to which this attribute or element type refers. This is used only on the attribute or element type corresponding to a column that contains a foreign key. For a discussion of the use and meaning of the property, see Modeling Relationships below.
 These metadata properties are also appropriate with minor modification to other schema syntaxes such as XML Data and SOX. Essentially, they become additional attributes on the element type or attribute type declaration.
 

Modeling Datatypes

 Traditional data sources tend to be strongly typed. While an XML document, by definition, will present its information in textual form, retaining knowledge about the underlying data type is essential. The metadata property dtype (as outlined above) will be used to capture datatype information. What set of datatype values should we use? While a comprehensive list of datatypes is an elusive (if not illusory) goal, a useful set has been compiled from the various schema submissions to the w3c. We'll adopt the convention of using these datatype names.
 
string number dateTime
boolean float date
uri int time
 A related problem arises around the issue of storage size. For example, how many bytes are needed to store a value of type "int" or how many characters long may a value of type string be? And even,"what is the precision of a value of type number?" We use the metadata property dsize to capture this information. The following meaning is assigned to values of dsize:
 
dtype dsize example
string maximum number of characters 23
float bytes (4 or 8) 4
int bytes (1, 2, 4 or 8)* * i1, i2, i4, i8 may be used instead of int to obviate the dsize attribute 8
number xy where x = digits allowed to left of decimal y = digits allowed to right of decimal 14.4
 Note that this encoding of datatype information within a DTD does not beget validation behavior by itself. Such validation is beyond the capabilities of XML 1.0 parsers. However, using these methods, you can make such information available to your custom code for proper validation. Indeed using notations matched in name to your dtype values you can bind a reference to actual validation modules to each datatype.
 

Modeling Relationships

 Much of the power and complexity of mapping data to XML comes from mapping the relationships between pieces of data. In the relational world this equates to the modeling of primary-foreign key relationships. Let's look at each in turn.
 

Primary Keys

 A primary key provides a unique value by which a single row of a particular table may be accessed. XML has a similar concept of an ID attribute that provides unique access to an element. Many implementation of DOM provide indexed access to such elements so leveraging the similarities is often desirable. However, a subtlety arises: XML IDs must be unique across the whole document, a primary key is unique only within that column.
 To provide the necessary global uniqueness, we use a supplemental pkey_id attribute to hold a version of the primary key data that we have made globally unique. To do this we take advantage of two facts: 1) the primary key is unique within the context of the element type that contains each row (named, as you'll see, after the table itself), and 2) the element type's name is unique within the document. So, to make the locally unique name globally unique, we prepend the element name to the key value. For example:
 
<EMPLOYEE pkey_id = "EMPLOYEE.2361">
 
<EMPLOYEE.NUM>2361</EMPLOYEE.NUM>
 
<EMPLOYEE.FNAME>Wilbert</EMPLOYEE.FNAME>
 
<EMPLOYEE.LNAME>Winston</EMPLOYEE.LNAME>
 
<EMPLOYEE.HIRE_DATE>4/4/88</EMPLOYEE.HIRE_DATE>
 
</EMPLOYEE>
 

Foreign Keys

 The presence of foreign keys within a table provides the actual glue that binds different tables together. Just as XML's ID concept provided a useful analog for primary keys, so too its IDREF notion provides a powerful analog to foreign keys. Of course issues of uniqueness scope intervene here as well. To accommodate them we use a similar technique. We create a new IDREF attribute for the table element whose name is derived from the column name (with an _idref appended). Values in a document will be constructed in a similar fashion as for pkey_id attributes (indeed the production must match exactly otherwise the whole point is lost). For example:
 
<EMPLOYEE pkey_id = "EMPLOYEE.2361">
 
<EMPLOYEE.NUM>2361</EMPLOYEE.NUM>
 
...
 
<PERF_REVIEW PERF_REVIEW.EMP_NUM_idref = "EMPLOYEE.2361">
 
<PERF_REVIEW.EMP_NUM>2361</PERF_REVIEW.EMP_NUM>
 
...
 Another problem that arises is the need to have the schema — rather than just the document — depict the relationships involved. Note that in the example above, it is the data of the PERF_REVIEW element that associates PERF_REVIEW with EMPLOYEE. So that the schema might "know" the relationship in the absence of a document instance we define that relationship using the metadata properties pkey and fkey. For example:
 
<!ATTLIST EMPLOYEE e-pkey NMTOKEN #FIXED 'EMPLOYEE.NUM'>
 
 
and
 
 
<!ATTLIST PERF_REVIEW.EMP_NUM e-fkey NMTOKEN #FIXED '
 
EMPLOYEE.EMPLOYEE_NUM' >
 

Nesting

 There is an alternative to the mechanism described above in some cases. This technique takes advantage of the fact that in XML relationship may be inferred from context (specifically containment) as well as through id/idref relationships. So, in our example, we can associate PERF_REVIEW elements with their corresponding EMPLOYEE elements by placing them inside the latter. For example:
 
<EMPLOYEE EMPLOYEE.NUM_id = "EMPLOYEE.2361"
 
NUM = '2361'
 
FNAME = 'Wilbert'
 
LNAME = 'Winston'
 
HIRE_DATE = '4/4/88'>
 
<PERF_REVIEW
 
REVIEW_DATE = '1/1/98'
 
REVIEW = 'lousy'/>
 
<PERF_REVIEW
 
REVIEW_DATE = '1/1/99'
 
REVIEW = 'worse'/>
 
</EMPLOYEE>
 Note that this is not always desirable and is often not even possible. The following conditions must be met for this to be appropriate:
 
  1.  The foreign key must not be nullable (i.e. optional).
  2.  It must be the only foreign key so modeled in the table.
  3.  Every desired row must refer to a row that will be included.
  4.  The foreign key must not point to the same table.
 

The Example Step-by-Step

 

Modeling Tables

 
  •  Table. The table itself becomes an element type. In the document each occurrence of an element of this type will contain a single row of the data. If we're modeling the columns of this table as attributes, the content model is EMPTY, if we're modeling the columns as elements, the content model is a sequence of the elements which correspond to the columns. In the later case we make optional (?) any elements whose columns' values may be null.
     
    <!ELEMENT EMPLOYEE EMPTY>
     
    or
     
    <!ELEMENT EMPLOYEE (
     
    EMPLOYEE.NUM,
     
    EMPLOYEE.FNAME,
     
    EMPLOYEE.LNAME,
     
    EMPLOYEE.HIRE_DATE,
     
    EMPLOYEE.TERM_DATE?
     
    )>
  •  Primary Key. If the table has a primary key we capture that information with the pkey metadata property introduced in Extending the DTD.
     
    <!ATTLIST EMPLOYEE e-pkey NMTOKEN #FIXED 'EMPLOYEE.NUM'>
  •  To provide id/idref access to key relationships we create a special ID attribute to contain a globally unique version of this key for each element instance. (See Relationships)
     
    <!ATTLIST EMPLOYEE pkey_id ID #REQUIRED>
 

Modeling Columns as Elements

 For each column:
 
  1.  Column Name. A new element type with the same name as the column is created. In the document, each occurrence of an element of this type will contain the value of a single column of a single row of data. Because element type names must be unique throughout the whole document, you should probably qualify the column's element type name by prefixing it with the tables' name.
     
    <!ELEMENT EMPLOYEE.TERM_DATE (#PCDATA) >
  2.  Column Data Type. Data types are captured using the dtype metadata property introduced in Extending the DTD.
     
    <!ATTLIST EMPLOYEE.TERM_DATE e-dtype NMTOKEN #FIXED 'date' >
  3.  Column Nullable. As noted in number 1, if the column may contain a null value then its reference in the table's content model is made optional.
  4.  Column Foreign Key. If the column contains is a foreign key, we use the fkey metadata property to record the column's element to which the key refers.
     
    <!ATTLIST PERF.REVIEW_EMP_NUM e-fkey NMTOKEN #FIXED 'EMPLOYEE.NUM' >
  5.  To provide id/idref access to key relationships, a special attribute of the table's element type may be created to serve as an IDREF link to the element corresponding to the other table. The attribute name is formed by appending "_idref" to the column element's name.
     
    <!ATTLIST PERF_REVIEW PERF_REVIEW.EMP_NUM_idref IDREF #REQUIRED >
 

Modeling Columns as Attributes

 For each column:
 
  1.  Column Name. A new attribute type with the same name is created. In the document, each occurrence of an attribute of this type will contain the value of a single column of a single row of data.
     
    <!ATTLIST EMPLOYEE EMPLOYEE.TERM_DATE CDATA #IMPLIED>
  2.  Column Data Type. Data types are captured using the dtype metadata property introduced in Extending the DTD.
     
    <!ATTLIST EMPLOYEE a-dtype NMTOKENS #FIXED
     
    'EMPLOYEE.NUM int
     
    EMPLOYEE.FNAME string
     
    EMPLOYEE.LNAME string
     
    EMPLOYEE.HIRE_DATE date
     
    EMPLOYEE.TERM_DATE date'
     
    a-dsize NMTOKENS #FIXED
     
    'EMPLOYEE.FNAME 32
     
    EMPLOYEE.LNAME 32'
  3.  Column Nullable. If the column may contain a null value then the attribute type is made implied, if not, it is made required.
  4.  Column Foreign Key. If the column contains is a foreign key, we use the fkey metadata property to record the table element and attribute to which the key refers.
     
    <!ATTLIST PERF_REVIEW a-fkey NMTOKENS #FIXED
     
    EMP_NUM EMPLOYEE.NUM'
  5.  · To provide id/idref access to key relationships, a special attribute of the table's element type may be created to serve as an IDREF link to the element corresponding to the other table. The attribute name is formed by appending "_idref" to the column element's name.
     
    <!ATTLIST PERF_REVIEW EMP_NUM_idref IDREF #REQUIRED >
 

Conclusion

 By adopting some simple conventions, XML Schemas can successfully model information sources such as relational databases. By capturing datatype, key relationships and id/idref information, extracted data can retain the metadata needed to facilitate processing at both side of information exchange. The process set forth above is straightforward and well suited to automation and has been implemented for a wide variety of databases in the current XML Authority product.
 

Listings

 

DTD with Columns as Elements

 
<!ELEMENT EMPLOYEE (
 
EMPLOYEE.NUM? ,
 
EMPLOYEE.FNAME ,
 
EMPLOYEE.LNAME ,
 
EMPLOYEE.HIRE_DATE ,
 
EMPLOYEE.TERM_DATE? )>
 
<!ATTLIST EMPLOYEE pkey_id ID #REQUIRED
 
e-pkey NMTOKEN #FIXED 'EMPLOYEE.NUM' >
 
<!ELEMENT EMPLOYEE.NUM (#PCDATA )>
 
<!ATTLIST EMPLOYEE.NUM e-dtype NMTOKEN #FIXED 'int' >
 
<!ELEMENT EMPLOYEE.FNAME (#PCDATA )>
 
<!ATTLIST EMPLOYEE.FNAME e-dtype NMTOKEN #FIXED 'string'
 
e-dSize NMTOKEN #FIXED '32' >
 
<!ELEMENT EMPLOYEE.LNAME (#PCDATA )>
 
<!ATTLIST EMPLOYEE.LNAME e-dtype NMTOKEN #FIXED 'string'
 
e-dSize NMTOKEN #FIXED '32' >
 
<!ELEMENT EMPLOYEE.HIRE_DATE (#PCDATA )>
 
<!ATTLIST EMPLOYEE.HIRE_DATE e-dtype NMTOKEN #FIXED 'date' >
 
<!ELEMENT EMPLOYEE.TERM_DATE (#PCDATA )>
 
<!ATTLIST EMPLOYEE.TERM_DATE e-dtype NMTOKEN #FIXED 'date' >
 
<!ELEMENT PERF_REVIEW (
 
PERF_REVIEW.EMP_NUM ,
 
PERF_REVIEW.REVIEW_DATE ,
 
PERF_REVIEW.REVIEW )>
 
<!ATTLIST PERF_REVIEW PERF_REVIEW.EMP_NUM_idref IDREF #REQUIRED >
 
<!ELEMENT PERF_REVIEW.EMP_NUM (#PCDATA )>
 
<!ATTLIST PERF_REVIEW.EMP_NUM e-dtype NMTOKEN #FIXED 'int'
 
e-fkey NMTOKEN #FIXED 'EMPLOYEE.NUM' >
 
<!ELEMENT PERF_REVIEW.REVIEW_DATE (#PCDATA )>
 
<!ATTLIST PERF_REVIEW.REVIEW_DATE e-dtype NMTOKEN #FIXED 'date' >
 
<!ELEMENT PERF_REVIEW.REVIEW (#PCDATA )>
 
<!ATTLIST PERF_REVIEW.REVIEW e-dtype NMTOKEN #FIXED 'string'
 
e-dSize NMTOKEN #FIXED '50' >
 
<!ELEMENT COMP_CHANGE (
 
COMP_CHANGE.EMP_NUM ,
 
COMP_CHANGE.REVIEW_DATE? ,
 
COMP_CHANGE.EFF_DATE ,
 
COMP_CHANGE.SALARY )>
 
<!ATTLIST COMP_CHANGE COMP_CHANGE.EMP_NUM_idref IDREF #REQUIRED >
 
<!ELEMENT COMP_CHANGE.EMP_NUM (#PCDATA )>
 
<!ATTLIST COMP_CHANGE.EMP_NUM e-dtype NMTOKEN #FIXED 'int'
 
e-fkey NMTOKEN #FIXED 'EMPLOYEE.NUM' >
 
<!ELEMENT COMP_CHANGE.REVIEW_DATE (#PCDATA )><!ATTLIST COMP_CHANGE.REVIEW_DATE e-dtype NMTOKEN #FIXED 'date' >
 
<!ELEMENT COMP_CHANGE.EFF_DATE (#PCDATA )><!ATTLIST COMP_CHANGE.EFF_DATE e-dtype NMTOKEN #FIXED 'date' >
 
<!ELEMENT COMP_CHANGE.SALARY (#PCDATA )><!ATTLIST COMP_CHANGE.SALARY e-dtype NMTOKEN #FIXED 'int' >
 

DTD with Columns as Attributes

 
<!ELEMENT EMPLOYEE EMPTY>
 
<!ATTLIST EMPLOYEE pkey_id ID #REQUIRED
 
NUM CDATA #REQUIRED
 
FNAME CDATA #REQUIRED
 
LNAME CDATA #REQUIRED
 
HIRE_DATE CDATA #REQUIRED
 
TERM_DATE CDATA #IMPLIED
 
e-pkey NMTOKEN #FIXED 'NUM'
 
a-dtype NMTOKENS 'NUM int
 
FNAME string
 
LNAME string
 
HIRE_DATE date
 
TERM_DATE date'
 
a-dSize NMTOKENS 'FNAME 32 LNAME 32' >
 
<!ELEMENT PERF_REVIEW EMPTY>
 
<!ATTLIST PERF_REVIEW PERF_REVIEW.EMP_NUM_idref IDREF #REQUIRED
 
EMP_NUM CDATA #REQUIRED
 
REVIEW_DATE CDATA #REQUIRED
 
REVIEW CDATA #REQUIRED
 
a-dtype NMTOKENS 'EMP_NUM int
 
REVIEW_DATE date
 
REVIEW date'
 
a-fkey NMTOKENS 'EMP_NUM EMPLOYEE.NUM'
 
a-dSize NMTOKENS 'REVIEW 50' >
 
<!ELEMENT COMP_CHANGE EMPTY>
 
<!ATTLIST COMP_CHANGE COMP_CHANGE.EMP_NUM_idref IDREF #REQUIRED
 
EMP_NUM CDATA #REQUIRED
 
REVIEW_DATE CDATA #IMPLIED
 
EFF_DATE CDATA #REQUIRED
 
SALARY CDATA #REQUIRED
 
a-dtype NMTOKENS 'EMP_NUM int
 
REVIEW_DATE date
 
EFF_DATE date
 
SALARY int'
 
a-fkey NMTOKENS 'EMP_NUM EMPLOYEE.NUM' >
 

XML Data with Columns as Elements

 
<?xml version ="1.0"?>
 
<!--Generated by XML Authority. Conforms to XML Data subset for IE 5-->
 
<Schema name = ""
 
xmlns = "urn:schemas-microsoft-com:xml-data"
 
xmlns:dt = "urn:schemas-microsoft-com:datatypes"
 
xmlns:xa = "www.extensibility.com/schemas/xdr/metaprops.xdr">
 
<ElementType name = "EMPLOYEE" xa:pkey = "EMPLOYEE.NUM" content = "eltOnly" order = "seq">
 
<AttributeType name = "pkey_id" dt:type = "ID" required = "yes"/>
 
<attribute type = "pkey_id"/>
 
<element type = "EMPLOYEE.NUM" />
 
<element type = "EMPLOYEE.FNAME" />
 
<element type = "EMPLOYEE.LNAME" />
 
<element type = "EMPLOYEE.HIRE_DATE />
 
<element type = "EMPLOYEE.TERM_DATE" minOccurs = "0" maxOccurs = "1"/>
 
</ElementType>
 
<ElementType name = "EMPLOYEE.NUM" content = "textOnly" dt:type = "i4"/>
 
<ElementType name = "EMPLOYEE.FNAME" content = "textOnly" dt:type = "string"/>
 
<ElementType name = "EMPLOYEE.LNAME" content = "textOnly" dt:type = "string"/>
 
<ElementType name = "EMPLOYEE.HIRE_DATE" content = "textOnly" dt:type = "date"/>
 
<ElementType name = "EMPLOYEE.TERM_DATE" content = "textOnly" dt:type = "date"/>
 
<ElementType name = "PERF_REVIEW" content = "eltOnly" order = "seq">
 
<AttributeType name = "PERF_REVIEW.EMP_NUM_idref" dt:type = "IDREF" required = "yes"/>
 
<attribute type = "PERF_REVIEW.EMP_NUM_idref"/>
 
<element type = "PERF_REVIEW.EMP_NUM" />
 
<element type = "PERF_REVIEW.REVIEW_DATE />
 
<element type = "PERF_REVIEW.REVIEW" />
 
</ElementType>
 
<ElementType name = "PERF_REVIEW.EMP_NUM" xa:fkey = "EMPLOYEE.NUM" content = "textOnly" dt:type = "i4"/>
 
<ElementType name = "PERF_REVIEW.REVIEW_DATE" content = "textOnly" dt:type = "date"/>
 
<ElementType name = "PERF_REVIEW.REVIEW" content = "textOnly" dt:type = "string"/>
 
<ElementType name = "COMP_CHANGE" content = "eltOnly" order = "seq">
 
<AttributeType name = "COMP_CHANGE.EMP_NUM_idref" dt:type = "IDREF" required = "yes"/>
 
<attribute type = "COMP_CHANGE.EMP_NUM_idref"/>
 
<element type = "COMP_CHANGE.EMP_NUM" />
 
<element type = "COMP_CHANGE.REVIEW_DATE" minOccurs = "0" maxOccurs = "1" />
 
<element type = "COMP_CHANGE.EFF_DATE" />
 
<element type = "COMP_CHANGE.SALARY" />
 
</ElementType>
 
<ElementType name = "COMP_CHANGE.EMP_NUM" xa:fkey = "EMPLOYEE.NUM" content = "textOnly" dt:type = "i4"/>
 
<ElementType name = "COMP_CHANGE.REVIEW_DATE" content = "textOnly" dt:type = "date"/>
 
<ElementType name = "COMP_CHANGE.EFF_DATE" content = "textOnly" dt:type = "date"/>
 
<ElementType name = "COMP_CHANGE.SALARY" content = "textOnly" dt:type = "i2"/>
 
</Schema>

The Use of Profiling in XML Documents   Table of contents   Indexes   Data Models as an XML Schema Development Method