|By Ajit Bhate, October 24, 2006|
Who says writing XML schemas is fun? It isn't, is it? But with NetBeans Enterprise Pack 5.5, the fun has just begun. In early '98, the W3C formalized the XML recommendation which is now widely accepted by the world, due to several of its virtues. Within three years, the W3C approved the XML Schema recommendation to provide a means for defining the structure, content and semantics of XML documents. The recommendation has been widely accepted since then. The Schema is expressed in XML, and it is widely popular, but is it easy? Let's consider the W3C recommendation. To simplify matters, Schema recommendation is divided into structures and data-types, each of which have more than 30 constructs and are expressed as complicated regular expressions. The number of constructs an XML document can have, is just over 10 and only half of those constructs interest most of us. Does the schema need to be so complex? Indeed it does! How do we simplify matters? The answer is "That's the purpose of the tools!" This article explores the XML Schema development functionality of NetBeans Enterprise Pack 5.5 and provides some useful tips and tricks to author and design XML Schemas efficiently, in a structurally sound way, and more importantly, in a simplistic way. So lets have some <fun/>.
Note: The term "the IDE" is used in this article to mean the NetBeans 5.5 IDE with NetBeans Enterprise Pack 5.5.
|-||Basics of Schema Design|
|-||Questions and Answers|
|-||Tips, Tricks, and Recommendations|
The IDE fully supports the XML Schema 1.0 recommendation. It provides several schema representations to assist users with different levels of expertise. It provides tools to find usages of various schema components and refactoring support, analyze schemas, retrieve schemas from the Internet to reuse, and architect schemas to comply with certain schema design patterns. We will briefly spend some time to understand basics of designing schemas and then explore some useful tips and tricks of the trade.
It is possible to design schema using a traditional top-down approach or a non-traditional bottom-up approach.
Let's first consider the top-down approach, where we start with an empty schema document and create schema constructs on our way to the destination instance document. As we know, XML Schema is expressed in XML. It has 36 structure constructs which are expressed in their own set of elements and attributes and define 44 built-in data types. Like a Java object, Schema defines some public or global constructs, which can be referenced in other schemas or in XML instance documents, and some private or local constructs, for internal purposes. Global definition of a schema element construct in schema file defines the document element of its instance document. Whereas global definition of a complex type allows creation of schema elements of that type, or derivations of the complex type. The user also needs to be aware of various content models defined in the types. In short, to use a top-down approach, the designer needs intermediate to advanced knowledge of XML Schema.
On the other hand, in the bottom-up or non-traditional approach, we start with an example instance document, and try to create schema that will represent the instance document. This approach requires very little knowledge about XML Schema. Although simple, it is sometimes less flexible and makes certain assumptions.
That being said, let's see how the NetBeans 5.5 IDE with NetBeans Enterprise Pack 5.5 tries to achieve a balance between these two approaches.
To create a new schema, simply create a new project or open an existing project in the IDE and create a new schema file using the top-level File menu, or pop-up menus available for nodes under the main project node in the Projects window. Make sure you choose an appropriate target namespace for your schema when you use the New XML Schema wizard. For more information about namespaces, see Namespaces in XML Schemas, Part 1: An Introduction.
To edit or view an already created schema, simply double-click the schema file node in the Projects window in the IDE. The schema file will be opened in the Schema view of the XML schema editor. At the top of the editor window, there are three buttons that let you switch between the views:
These three views allow navigation to other views for schema components in context. This allows for editing in many views and achieves simplicity and flexibility at the same time.
Yes, there exist many design patterns for XML Schema. Depending upon the end usage of the schema, it may be better to stick to a certain design pattern to increase simplicity and adaptability. Sometimes there is no one design pattern that can fulfil particular needs and a blend of patterns is more suitable. The IDE supports four schema design patterns and lets you transform existing schema files by applying a different design pattern. Introducing Design Patterns in XML Schemas provides more information about design patterns.
Today's programming paradigm heavily depends upon reusability of building blocks. The XML Schema recommendation allows for distributed schema design. Schemas can be referenced from other schemas using special schema constructs like import, include and redefine. It is possible to retrieve XML Schemas that exist on the Internet and reuse them in local schema files in the IDE. For more information, see Working With Multifile Schemas.
In previous section we mentioned that XML Schemas can be referenced by other schemas. This means that change in a schema element may require all the references to change. It would be a nightmare if these references have to be changed manually. But not to worry with the IDE. There is a special pop-up menu, called Refactor, available for all the schema components that can be referenced from outside of (or within) the schema. It is sometimes useful to find the usages of such components for various purposes. The Find Usages pop-up menu displays the usages in useful graphical fashion. Be sure to visit Analyzing XML Schemas to know more about these techniques.
Lets have a look at the three representations (Schema, Source, and Design) for a sample XML Schema.
And you are done.
You can do this in several ways:
In both cases, the old contents are preserved.
The changes made in the Design view are immediately reflected in the source. Don't believe it? Do the following test:
You can also check this behavior with the Schema view. Note that the changes made will not be saved into physical file, unless you explicitly save the file, or it is saved by some other action like validating the schema.
Derivations from types are a top-down approach. This means it can be done using the Schema view.
You can also invoke a customizer to change the existing definition of a type, to derive from another type, using the Customize option in the pop-up menu.
Reordering elements in a sequence can be done in Schema view. Navigate to the sequence where you want to reorder elements. Select the sequence node, right-click and choose Change Order. Select the correct ordering in the Change Order dialog box.
As the name suggests, global types have a global scope. They can be referenced directly in an element definition or can be used as base to derive other new types. They are defined directly under the top-level schema element and are named. The name is used as a unique identifier (combined along with the namespace) used for referencing. On the other hand, local types are defined directly where they are needed, just like inline definitions. They have local scope, and are anonymous, meaning they cannot be referenced.
So, to convert a local complex type into a global type, you must name the local complex type and define it under the top-level schema element. Then the component which has the local type defined inline, can reference the global definition directly. In the IDE, there is no direct way to achieve this. However you can use this little trick to achieve this in no time:
If you prefer drag-and-drop functionality to copy and paste, use the tree mode of the Schema view, and drag the children of the local type onto the newly created global type.
If you want to make all the types global or all the types local, you can also consider applying a design pattern that will or will not create types.
Only Global Elements, Global Attributes, Global Simple Types, Global Complex Types, Global Attribute Groups, and Global Groups can be referenced outside of schema. In some cases, local elements and attributes are referenced by Selectors and Fields. To find references to these components, simply select the component in the Schema view, right-click and choose Find Usages from the pop-up menu. The results of find usages will be shown in the XML Usages window, in graphical form.
It is possible to copy schema components from one file into another. Here is how:
The paste function makes sure that named schema components have unique names. One must note that it is possible to copy components of different types (elements and attributes), but you will not be able to find a component where you can paste it. It is however possible to copy components of the same type from multiple parents and paste them into a parent component. An example would be to explore two sequences in the tree mode of the Schema view, copy the local elements under the sequences, and paste them into another sequence.
To rename a component that is referenceable:
To delete a component that is referenceable:
If a schema is made invalid, it is impossible to render it in the Design view. The validation errors can be fixed by running the validation from the Source or Schema view and fixing errors one by one. The error report is shown in the Output window. If you started with valid schema, that was rendered in the Design view, you may also want to undo recent modifications until the Design view renders your schema again.
In each of the views, a Go To option is available on the pop-up menu. If you want to see the schema representation of an element in the Design view, simply select Go To > Schema from its pop-up menu. These navigation actions are also provided in the XML Usages and XML Refactoring windows and in the Navigator window.
The Design view is most suited for beginners, whereas the Schema view is more suited for advanced users. However, it is also possible to have a mix and match development. Remember that if a schema becomes invalid, the Design view cannot render your schema. It is very difficult to create invalid schema using the Schema or Design views, but it can happen. Validation errors can be fixed and modifications can be undone to make the schema valid again. There is no or minimal support for simple types, attribute groups, and groups in the Design view. Derivations of existing complex types is not supported in the Design view. These tasks can only be performed in the Schema view.
The Source view does not have the many convenient features provided in the Schema and Design views. It does have support for code completion and code folding. The Source view also allows for fast editing of a schema construct around the cursor, using the Properties window. However, in the Source view, it is easy to turn schema invalid or not well formed, which may mean that other views will not be able to render your schema. Refactoring and Find Usages functionality is not provided in the Source view. The Source view is the only view you can use to add XML comments or to reformat the source. Note that whenever new elements are added from other views, formatting is preserved.
Grayed out components in the Schema view imply that they have been inherited from a different component. In this case, they are shown only for informational purposes and are read-only. You can go to the actual definition by right-clicking the component and choosing Go To > Definition from the pop-up menu.