Vendor-Neutral and Portable Databases via XML

Aditya P. Bansod

 

December 1999

 

 

 

 

 

 

 

 

Abstract

This paper explores the requirements needed to build a vendor neutral database system. This is accomplished by understanding the metadata of a relational database and using it to form an abstract model that can be applied across vendors. This is done by taking a detailed look at the fundamental concepts of a database and abstracting them to vendor independent levels. From there, the paper discusses how to translate each of the aforementioned concepts from the meta-model into XML documents and addresses the issues that arise there. Lastly, this paper deals with using XML to define incomplete and semi-formed databases. This is further expanded by discussion the usage of XML databases as a data transfer mechanism between dislocated database systems.

 

Keywords: databases, metadata, portable, semi-formed, XML

 

Contact Information:

Aditya P. Bansod

Strevda

26845 Bridlewood Drive

Laguna Hills, CA 92653

(858) 638-1864

aditya@strevda.com


 


Vendor-Neutral and Portable Databases via XML

1 Introduction

Distributed environments and heterogeneous networks often times put large demands on the portability of applications. Systems such as software, hardware, and databases are often required to be able to move to the latest technology or change vendors. This can occur for various reasons such as cheaper prices on different platforms, strategic alliances with new vendors or better efficiency with new systems than the ones currently being used. This paper will deal specifically with the realm of Vendor-Neutral Portable (abbreviated as VNP) database: systems that can be moved across vendor boundaries with assurance of integrity.

This type of exchange has become a possibility with the acceptance of the World Wide Web Consortium’s eXtensible Markup Language (XML). XML, as originally conceived, was designed to be a platform and system independent method of data delivery across the web [1]. However, its applications are much more significant than that. By nature, XML makes no assumptions about the type of data it is marking up. The semantic rule to XML is the “tagged” nature of its format (i.e. <start>data</start>) and the nesting ability of the tags. This leads developers to be able to use XML to define virtually anything of wish, such as mathematical formulas, insurance claim data, object models, text documents, etc. It can basically be used to transmit and store any type of structured data. Further, this structure can be defined in a Document Type Definition (DTD).

With XML the way is given for us to be able to store a database in a vendor-neutral nature. With the establishment of a standard method of encoding databases, it is possible to move a database from Microsoft SQL Server to Oracle. This paper will deal only with implementations issues, the general structure a XML Database would take, and how to develop a modular database. It will not define a DTD for the creation of a specific standard, nor will it deal with issues such as moving PL/SQL code to T-SQL and other vendor specific issues. It will mostly deal with the transcription of data and structures into an XML format.

1.1 Motivation and Needs

The need to be able to move databases between vendors is quite noticeable as platforms and technologies change rapidly. A system once designed to run on a mainframe database could be moved fairly easily moved to a leading edge database product if aided by VNP databases. Likewise, a current database could be moved to a different vendor by using XML as well. Because XML defines that it supports Unicode [1], the use of a VNP database could be used to internationalize current databases.

Often times, new hardware or features in a different database package will compel an organization to move their database system to a new platform. Changes in hardware such as an attractive price per performance ratio on a different processor architecture or the need to scale upwards can at times cause databases to either break or need to be re-implemented. Such a tedious process can be alleviated if the structure, features, and data of the previous database can be transitioned easily. This is where something such a VNP method of representing a database can be of great use.

Almost all databases provide a method to export their structures and data currently to SQL. The problem with this is that it is very vendor specific. For example an Oracle SQL export will not work with Microsoft SQL Server, due to differences in PL/SQL and T-SQL. As standardized as SQL attempts to be, each vendor’s additions to the language make it infeasible to use as a VNP database. The need to be able to move databases from one vendor to another’s creates the need for a methodology to be able to export these databases so that the general structures and data can be preserved.

Further, there is a need to provide a vendor-neutral method of exchanging data from heterogeneous data sources in a standardized manner. There is currently no method of moving data from one type of database to another efficiently and that is an open standard. This would allow for more efficient synchronization of different data stores as well as free development of such standards.

1.2 Paper Layout

In the next section we will define the basis of the databases that we will deal with and what types of data we wish to manipulate. Section 3 describes the actual mappings that would occur between a database and an XML file. It shall deal with how objects such as data types, security realms, tables, columns, and so on are translated into an XML file. Section 4 outlines potential problems that can arise when moving from vendor to vendor and discusses semi-structured and incomplete databases. Section 5 recaps the work of this paper.

2 General Structures of Databases

To begin a discussion of the structure of databases it is necessary to introduce the concept of metadata and its relation to a relational database. Metadata is the information describing the real information; it is the data about the data. For example, the text of a book is the information, and table of contents is the metadata for the book. The concept of metadata is relatively new in the field of computer science, only recently becoming even a recognized point of discussion. To explain what metadata is, we briefly look at an example using cellular phone transactions.

When a phone number is placed, volumes of data are stored about the call. The actual data about a cellular phone record would be the number the person called, the phone number that the call originated from, perhaps the credit-card number to bill the phone call to. However, the metadata about this phone call would not be this actual data, but an abstraction of this data. It would only be the fact that we're recording the phone number, the credit-card number, but not that actual information itself. Metadata is useful for managing the data itself. Because the user has an understanding of the structure of the data (i.e. the metadata), it is possible to better handle, store, and predict changes in the actual data.

In terms of relational databases, the metadata of any database is the next highest level of abstraction about the information. From the previous example of the cellular phone system, in each row of the table would be stored particular information regarding a call. The metadata for this would be the names of the columns. The metadata for the columns of the table is the table itself. The metadata for the tables is the databases. By analyzing this paradigm, we see that each level higher describes the level below it.

2.1 Database Model

The development of a model for a database that is abstract enough to be able to be applied across vendors begins by analyzing the metadata and formulating a general model of a relational database. All relational databases contain some core types on information:

1.       Tables – store columns and rows of data and make up the basis of a database

2.       Stored Procedures – compiled statements of database code, generally with parameters

3.       Views/Stored Queries – queries that generally depict a commonly used view of the data

4.       Users – give and restrict access to database objects

5.       Groups – collections of users

6.       Permissions – how the user is allowed to interact in the database

We shall use these six objects as the core of our database that we wish to model. Since we are developing an XML version of a database, it is necessary to address what each of these objects contains and how that affects the other objects in the database. As a cursory overview, a “Table” would store columns, indexes, information about its owner; the “Users” would store information such as the names of the users, passwords, and so on.

Further, we will deal with two levels of information for most objects in a database. The first being the properties of an object that are certain characteristics held by an object. These properties some times unique to the object, such as the name it has or an ID, and others are not, such as an objects owner. Properties generally will have a cardinality of one and are relatively immutable. The second type of information regarding each object is its contents: the data that it holds inside of it. This does not necessarily have to be unique and it is mutable.

2.1.1 Tables

Tables are the basic construct used to hold data in a database. They have certain properties that are standard across most database systems. The ones what we will deal with are table name (which we will assume is unique in the database’s namespace) and table owner. There are many different properties that can exist for a table, but these are the only ones we will need to deal with. More importantly for a table is its contents: the information that it stores. Here we have columns, data types, data, relationships, and a whole array of other types.

Each table is comprised of columns, which themselves carry the name property. These encode the data for the table using a spreadsheet type of view. Each column also carries another property: data type. This data type is the type of information that the column is storing. Examples of data types are characters, integers, float, etc. Some of these data types require further encoding of their properties: a string would have a property of its length; a float would have a property of its maximum precision and so on.

In dealing with the most abstract level of databases across vendors, we can assume that the table-column relationship exists (i.e. a table contains columns of cardinality one or more). Further, we know that each column is of a specific and immutable data type. We shall not delve into defining a set of data types for abstraction outside a few of the generic data types that are seen across databases and modern programming languages: string (we shall ignore a character data type, with the intent that the string type can be used in place of it), integer, float, and boolean.

Lastly, each column can be indexed for faster lookups. This, however, is stored as a property of the column, because each column can have only one index associated with it. It is not necessary to actually store the index for the data in an abstracted model of a database, because that is system dependent, thus it would be generated dynamically be a database system.

The subject area that we have covered so far about tables is nothing more than the simple data storage end of a database. To complete our abstraction and discussion of the table, we shall now discuss the relationships between columns in disjoint tables. Each column has the possibility to be related to another column of another table using a relationship. This falls into the category of a contained type of information for a column. The cardinality of a relationship is zero to many because it is not necessary for a column to be related to another column, yet it can also be related infinitely. We also have to consider that relationships can exist bi-directionally. In those cases, both columns would contain the referential information, and vice-versa, in a uni-directional relationship only the client-end column would contain the relationship specification.

Text Box: Figure 3 - ColumnsText Box: Properties	Name
	Data type
	Extra Type Info
	Index
	ID
Contents	Data
	Relationships

Those are the basic abstract concepts of a table and its related components that are generic across all database platforms. Using this as a base of information, we can see the meta-database and how it will be used to form a generic representation of a database using XML. Much of the table concept was presented in such a way to facilitate the translation to a structured and nested XML type of system.

2.1.2 Stored Procedures and Queries

Any discussion of an abstract stored procedure and query is significantly difficult due to the disparate nature of their implementation across vendors. Many stored procedures are SQL statements. Although SQL is fairly standardized, much of the functionality used in one vendor’s implementation does not exist in another’s.  More recently, some databases have been allowing stored procedures that are written in Java, which additionally complicates the issue. For simplicities sake, we shall not delve into how to abstract stored procedures and queries specifically; rather we shall only deal with their structure and meta-structure.

Both stored procedures and queries have certain properties that are common to them including their name and owner. From here, additional properties need to be defined in order to abstract both of them. Other properties of a query may include things such as the table that it is processing off of, maximum time to run, number of rows to return, etc. Additional properties for stored procedures would be the parameters that it takes and their data types. Stored procedures and queries are simple objects, with little left to them except their contents, which would simply be the “code” of the stored procedure or query.

2.1.3 Users, Groups, and Permissions

It may seem extraneous to discuss security details when developing a meta-model of relational database; but, because of the very open nature of many database systems and the connectivity offered by the Internet, it is quite necessary to detail at least some basic and general information. When describing objects in general, as we have been before, the owner of the said object has always been included as a property of each of the objects. These owners shall map to instances of a user.

Quite simply, a user is a person who is allowed to transact in the context of the database. A user contains very few properties at all. The only property that a user contains is a unique ID for the user, which can be system assigned, or a username, or both. The rest of the information about a user is really the contents of that user. Thus, his name, password, location, phone number, and so on are the contents of the type. This is an ideological decision, because a user object would “contain” all the information about it. The properties should only be things that are relatively immutable.

Each user can further belong to zero to many groups. Groups contain certain other properties, such as an id as well, and their contents can is highly variable depending on the “ideology” of the database. This is because the membership of groups can either be stored in the group itself, i.e. the group contains pointers to the users that belong to it, or the users contain pointers that reference the groups they belong to. For the sake of our discussion, we shall use the former interpretation. This is simply to create a clear and abstract view of the database without regard for performance or optimizations.

As for permissions, we know that each user and each group can have certain permissions into a database object. That could be encoded into each object individually, but that would leave to high overhead. Instead, that data should be contained in the user or group. There are fairly standard permissions that exist across most database systems, such as allowing (and disallowing) selects, inserts, updates, creations, etc. The permissions object would be part of the content of each user, and would have a property of a type, as in what type of permission this defines. The content of a permissions object would be the objects that it defines permissions for (in context of that user), thus it would be references to other database objects.

3 Databases in XML

In the last section, we completed discussion of a generalized meta-model for all databases. This model allows us to look across many different vendors’ implementations of a relational database and view them in a similar manner. This is the first step in allowing them to be actually moved between vendors. The next step is defining a portable method of moving the data that we previously abstracted: XML. We shall approach the how to render data into XML in the same manner as we did with our meta-data discussion.

3.1 Overview of XML

But first, we shall briefly discuss the structure and content of an average XML file. Figure 4 is an XML document that is similar to the ones that we would expect to be used in a VNP rendering of a database. Let us being by examine the structure of this document. All elements in XML are called tags, as they “tag” the information, revealing the structure of the document. The first line defines this file as a version 1.0 XML document. This is standard across all XML documents, regardless of the data they will contain. This first line can also contain information about a Document Type Definition (DTD), which details the structure of the XML document.


The next line defines the top-level element for the file. In this case, it is DATABASE and has a property of name. Its contents are the various things that a database can contain, such as the TABLE in the example. As we can see, the hierarchical nature of XML leads this nested structure to continue indefinitely deep. This structure helps preserve the order and structure of the data. As we look further in the document, we can see for each tag we open, we are required to close it as well in order to create a well-formed document.

3.2 Properties and Contents

In earlier discussion, the difference between properties and contents was made in terms of the meta-structure. Here we can see how that applies in practice in the XML. As we had mentioned earlier, things such as IDs and names would logically be properties because they exist only once and are description-type objects. Thus, in our XML, they are stored as parameters to the tag, i.e. the DATABASE tag had a property of name, which was given as a parameter to the tag.

The content of this tag is the information stored in the database. So, there are elements such as a column in our given example. This can include other objects that we had defined earlier such as stored procedures, users, groups, and queries. Each of these objects starts and ends their own tag, and can further have properties and contents of their own. All elements within another element must make sense in terms of what they are contained in. Since we are not defining a DTD to specifically spell out the rules of this, we will use logic, with the understanding that a column cannot contain a table and so on.

3.3 XML Rendering of a Database

Since we have a very easy footprint to follow of what a database looks like abstractly, we can easily begin setting down rules and ways for this abstract data to be translated into XML. Many of the objects that we had defined in section 2 can very well be directly written into XML with little need for any additional work on the translator’s end. There is some discussion needed to cover the creation of the IDs which will be used to connect objects out of a containment scope; example of this are users to groups, columns to related columns, etc.

IDs must be unique across all elements in an XML document. Therefore, the generation of them can be somewhat complicated. Very simply they can be sequential numbers generated by the exporting package as different elements are written out to the XML file. Or, they can be the internal ID numbers that may be stored by the database system that are written out to the XML file. Regardless, the IDs must be unique not only in each element, but in the scope of the entire document. This allows for traversal of the document via the IDs. Please note that the IDs used in the examples generally are arbitrary and do not follow a traversable logic.

3.3.1 Tables

As we saw in Figure 4, tables are contained within Databases. Each table has a <TABLE> tag, which has the properties that were described in Section 2.1.1. These are the name, owner, and ID. The name must be unique in the scope of all the tables and the ID must be unique across the XML document. The XML tag of a Table element is as follows:

<TABLE name = "sales" owner = "sa" id = "1">

...

</TABLE>

The TABLE tag beings the table section, and it assigns the values of the properties that are required to be assigned. At the end of the Table is a closing </TABLE> tag, and the "/" symbolizes that this tag is the end of the TABLE tag. As a note, no properties can be assigned to the closing tag of an element. That is all that is needed to define only a table object. Without any columns, this would suffice to define a table that could be imported into any database system. Since this is a very rare case, and most likely quite useless we shall begin discussion of the Column object.

The column object is perhaps the most critical element in a database since it stores the actual data of the system. However, that does not make it difficult to translate it to XML. The nature of data lends itself to an easy move to any type of structured format. A column, as we had described earlier (and in Figure 3), has a handful of properties. These are its name, ID, indexed, data type, and extended type information. The index property is used as a boolean type to determine whether of not the column should have an index generated for it when it is imported into a database system.

The data type is used to determine what rules the contained information should be bound to upon import (and export). We have described earlier the core data types that we shall be dealing with, and those were string, integer, float and boolean. The extended type information property (exttypeinfo) is used to encode information about a type that is sometimes needed. For example, an exporting database system would want to explicitly state the length of a string, or the accuracy of a floating-point number. This can be encoded in the extended information property. With all that said, here is an example of a column start and end tag.

<COLUMN name = "value" datatype = "float" id = "2" exttypeinfo = "5" index = "true">

     <RELATIONSHIP idref = "12">

<ROW>103.20</ROW>

     <ROW>125.28</ROW>

</COLUMN>

All the ideas we covered about the column tag are shown here. This column is called “value” and is a floating-point number with a precision of 3 (the exttypeinfo). It is an indexed column, and has an ID of 2. The contained elements of this tag are the relationships this column has with other columns, and the rows of data that it holds. The relationships are held in the relationship tag, with the idref property pointing to the other end of the relationship.

Earlier we had discussed the possible directions for relationships. They could be either uni-direction or bi-directional. In the case that relationships are bi-direction, the relationship tag written should be contained in both columns, thus enforcing the referential integrity. If it is a uni-directional relationship, the tag should only be written in the client end of the relationship. For example, if there is a foreign key relationship between column A and column B, where B is supplying the keys for A, the tag should be written into column A, pointing to column B. It would be illogical to write it vice versa, as that would require more processor intense integrity checks.

The last point that needs to be made about the column is the row tags within it. It is absolutely necessary to have the number of rows in each column for each table to be equal. If they are not, it leaves a vague question for the importing software on how to resolve the dead space problem. In section 4, we shall discuss semi-formed databases and what potential solutions to the dead space problem. But with in order to have a fully formed document with all parts of the database accounted for, it is imperative that the numbers of rows are equal across columns.

3.3.2 Stored Procedures and Queries

Stored procedures and queries are rather simple beasts conceptually in databases, but they become more complicated when they have to move to XML. We shall start by discussing queries. Queries are basically a collection of SQL statements that compile data from different tables of information. Below is an example of a query coded in XML.

 <QUERY name = "sales_report" owner = "sa" id = "3">

     ... sql_statements ...

</QUERY>

The XML shown here simply declares a query named sales_report, with the owner and ID. The content of the query is the SQL statements that it would execute. This can cause problems that we had discussed in section 2.1.2, such as interoperability of different SQL variants. For the purpose of this discussion it is not necessary to try to define a generic SQL language, but it should be noted that ANSI SQL should be a potential language considered to use for vendor-neutral SQL.

The procedure for creating XML for stored procedures is somewhat the same, but with some additions. To begin, there are additional properties needed. A stored procedure acts like a method: it takes parameters that are passed to it, processes them, and sometimes returns a value. Thus, we need to encode that information. The content would have a couple of parts, the parameters that this stored procedure takes (if any), as well as the actual code that did the processing

<STOREDPROC name = "unique_sales" owner = "sa" id = "4">

     <PARAMETER name = "startyear" datatype = "int"/>

     <PARAMETER name = "endyear" datatype = "int"/>

     ... sql_statements ...

</STOREDPROC>

This example shows two parameters, which define a start year and end year for something this stored procedure is to do. This uses a XML construct that we have no shown before, mainly a self-closing tag [1]. This tag ends with a "/", and at initial examination it seems as if it does not have a closing tag at all. In fact, that trailing slash signifies that this element starts and stops without any content. By using such a tag, we keep the XML clean and easier to read.

3.3.3 Users, Groups, and Permissions

The encoding of users and groups is a sticky issue because it raises implementation issue. We will use in our examples the method where the list of users is assigned to the group, rather than the user enumerating the groups that he belongs to. This is just for our sake, as the XML is only marginally different in either case. To begin a discussion of a user, we know that a user only has two properties, and those are his ID and Username. This could in fact be consolidated into one ID, as we could use a simple numerical ID for user references and encode the world-friendly username as part of the contents of the user. The user can contain permissions as well. As an aside, information such as passwords may be encrypted for whatever purposes assuming that when doing the import of the XML into a database they can be understood and functional. Either way, the XML for a user is quite straightforward.

<USER name = "sa" id = "5">

     <FIRSTNAME>Foo</FIRSTNAME>

<LASTNAME>Bar</LASTNAME>

<PASSWORD>foobar</PASSWORD>

</USER>

Groups are equally easy to encode in XML. They have the exact same properties as a User does, and when making owner references, they can point to a group as well for flexibility. Their content can be a number of things, such as a listing of users (via ID references), a listing of permissions that the group has, or potentially other groups. An example of this follows.

<GROUP name = "dbadmin" id = "6">

     <USER idref = "5"/>

     <USER idref = "12"/>

     <PERMISSION type = "allow_select">

           <TABLE idref = "1"/>

     </PERMISSION>

</GROUP>

In this example, this group contains two users, of ID 5 and 12. The permissions tag defines a permission of allow for selections for this user. At this point, if there were more allow_select, they would be enumerated into that permission tag. In the example, we only have one object where we have the allow_select permission for, and that is the table. Notice how it is a self-closing tag, and does not contain full-fleshed table information. That is taken care of by the id reference back to the actual table we are applying this permission to.

4 Cases and Issues

Thus far, we have looked at how to take a database and abstract it conceptually so that it is vendor-neural. Then we proceeded to take this vendor neutral model and translate it into an XML document that could be applied to virtually any database system. While doing this, we came across some potential setbacks as well certain features that cannot happen in classic databases that can be done with XML. The main problem was how to take specific vendor database programming languages (such as T-SQL or PL/SQL) and use them in our stored procedures and queries.

The main suggestion to alleviate this problem is to use ANSI SQL as a vendor neutral method of moving database code. Other than that, it is not in the scope of this paper to define a new database language or even to give a detailed methodology on how to convert proprietary code into something standard such as ANSI. However, translators can be made for simple issues such as the conversion of one date function into another across SQL varieties. More complicated things when a database is heavily vested in a proprietary technology would need significant more work to move itself to a vendor neutral level.

One of the features of XML is the ability to have a semi-formed database still be complete. That is meant in the sense that it is possible to have meaningful information without having to define a full XML document [2]. We could be given only a table definition with perhaps an associated user element. With this information, we could construct a full database if we saw fit, or take this information and import it into another database. Take the following example as if it were an entire XML document (note: parts of the elements have been left out for brevity):

<TABLE name = "papers" id = "1">

     <COLUMN name = "author" datatype = "String" id = "2">

           <ROW>John Smith</ROW>

           <ROW>Jack Williams</ROW>

     </COLUMN>

     <COLUMN name = "title" datatype = "String" id = "2">

           <ROW>My Own Life</ROW>

     </COLUMN>

</TABLE>

As we can see immediately here, there is a lack of a containing database tag, there are no owners assigned to the table, as well as the fact the first column has more rows than the second. Because this is an XML document, with no stated structurally defining limits, this table can exist on its own in a database. The fact it has no database tag is irreverent, because this table element alone gives enough information to create a freestanding object. The owner of it would be assigned as seen fit by an importing utility to whatever user it sees fit.

In a conventional database, it would have been impossible to have more rows in one column then another. Because of the looseness of the documental structure, we can allow that case here. Of course this opens the issue of what to do with empty space that would be caused by importing this document into a database. For all likes and intents it could be left as nulls or whatever the default type of the empty column is. The fact is, this allows for databases to be semi-formed. The hierarchal structure of the database and XML document is still paramount, but the lax nature allows for more freedom and efficiently in creating the XML where the database may not be fully defined. XML allows for more growth and flexibility while designing the database because it is not bound by conventional standards. The author can break convention and create a semi-formed document that is still valid.

This leads into a discussion of using VNP for data transfer over high latency networks, the prime example being Internet. Because we have the ability to take data from a structured source, and move it into a vendor neutral format (as well as XML being text), we now have the ability to take information from heterogeneous data sources and move it around. This could have been accomplished with current technologies such as ODBC, but they rely on custom protocols and support layers. A two-phase commit application that runs on separate databases could be extensively simplified with the support of VNPs.

To begin, XML is a text format, so compression algorithms such as LZ variants can perform very efficient compressions at high speeds. Next, the simple nature of XML as well as the ability for it to represent semi-formed databases and information enable a very efficient manner of exchanging data. For example, let us suppose that at two different sites the same data was housed for backup purposes. One site was running SQL Server and the other running Oracle. It would be a simple matter for when a write operation occurred at one, the XML for the data change or update could be replicated at the other one by method of a semi-formed database or table. This promotes a more open application of databases and could help database users to be able to use the features of different types of databases while maintaining the same information store that they operate on.

5 Conclusions

Vendor neutral and portable databases open up an exciting area in the field of interoperability. They allow for databases from one vendor to be rendered into a lightweight format, then moved and imported by virtually any database software that would support the lightweight format. This paper has examined using XML as a portable format. From the work done here, it is obvious that XML has a huge amount of applicability in the field of databases as its nature directly lends itself to working with a database.

We began by examining the metadata of a database and then following by translating the application of that metadata into XML. This discussion of the databases metadata provides a solid background for creating any type of vendor neutral format, because it allows us view a database above the implementation specific level. The choice of using XML as the format gives us options such as the creation of semi-formed databases that are could be highly useful in the e-Commerce and data warehousing industry.

Semi-formed databases and VNP XML documents allow for a much broader and open application of databases. The boundaries previously formed by specific protocols and database requirements mostly disappear when a database is represented in XML. Since XML is an open format, the ability to extend the format is quite common and prevalent. We hope that development of vendor-neutral formats continues, specifically in XML, so that the open nature fostered by the New Economy can lead to high degrees of interoperability and efficiency.

6 Acknowledgements

Mr. David Ochi and Mr. Allen Ibara read and criticized this paper while it was in progress and helped add content and substance to it each time. Mr. Tobin Fricke and Mr. Pradeep Bansod read other drafts and helped as well. I would like to thank you all.

7 References

[1]  Bray, T., Paoli, J., Sperberg-McQueen, C. M., “Extensible Markup Language (XML) 1.0” , http://www.w3.org/TR/REC-xml, 10 Feburary 1998

[2]  Grosso P., Veillard D., “XML Fragment Interchange”, http://www.w3.org/TR/WD-xml-fragment, 1999 June 30.