3D PLM Enterprise Architecture |
Middleware Abstraction |
Creating XML Documents with DOMCreating a new XML document from scratch using the DOM API |
Use Case |
AbstractThis article shows how to create a new DOM tree from scratch using the DOM API and how to save it to disk as an XML file. |
This use case shows how to create XML documents from scratch using the DOM API. You will learn to create the most common XML constructs: document type declarations, elements, attributes, comments, and text nodes. You will learn how to save these constructs to disk to obtain an XML file.
[Top]
The CAAXMLDOMCreate Use Case is a use case of the CAAXMLParser.edu framework that illustrates XMLParser framework capabilities.
[Top]
This use case creates a new XML document in memory, then saves it to disk under the specified name. Upon completion, you will obtain an XML file describing a car, created programmatically through DOM, with the following content:
<?xml version="1.0"?> <!DOCTYPE car SYSTEM "automotive.dtd"> <car> <!--list of parts for a convertible car--> <part name="seat" quantity="2"></part> <part name="wheel" quantity="4"/> <part name="engine" quantity="1">low consumption engine</part> <part name="body" quantity="1">weight must be < 1200 kg</part> </car> |
[Top]
To launch CAAXMLDOMCreate, you will need to set up the build time environment, then compile CAAXMLDOMCreate along with its prerequisites, set up the run time environment, and then execute the use case [1].
The use case should be launched as follows from the command line:
CAAXMLDOMCreate <outfilepath>
where <outfilepath>
is the path of the XML file,
which will be created.
[Top]
The CAAXMLDOMCreate use case is made of one file located in the CAAXMLDOMCreate.m module of the CAAXMLParser.edu framework:
Windows | InstallRootDirectory\CAAXMLParser.edu\CAAXMLDOMCreate.m\ |
Unix | InstallRootDirectory/CAAXMLParser.edu/CAAXMLDOMCreate.m/ |
where InstallRootDirectory
is the directory where the
CAA CD-ROM is installed.
[Top]
To create a blank XML document, populate it and save it to disk, there are seven main steps:
# |
Step |
---|---|
1 | Create the V5 DOM Component |
2 | Obtain the DOM Implementation |
3 | Use the DOM Implementation to Create a Document With the Proper Document Type |
4 | Use the Document to Create Elements, Texts, and Comments |
5 | Create the Tree Structure by Positionning the Elements, Texts, and Comments with Respect to Each Other |
6 | Save the Document as an XML File |
7 | Manage Errors |
Please note that most of the APIs from the XMLParser framework return
a HRESULT. To avoid excessive indentation of the code, which
would cause poor readibility, the following coding style has been used:
the whole code is put in a do {} while(0)
loop; if one of the
APIs returns a bad HRESULT, the execution is stopped with a break
and the error handler is invoked.
HRESULT hr = E_FAIL; do { hr = XMLParserAPI_1(); if (FAILED(hr)) { break; } hr = XMLParserAPI_2(); if (FAILED(hr)) { break; } ... hr = XMLParserAPI_N(); if (FAILED(hr)) { break; } } while(0); if (FAILED(hr)) { // Error handling code. } |
[Top]
... CATIXMLDOMDocumentBuilder_var builder; HRESULT hr = ::CreateCATIXMLDOMDocumentBuilder(builder); ... |
The first step to work with DOM is to instantiate the V5 DOM
component. The V5 DOM component can be created by calling the CreateCATIXMLDOMDocumentBuilder
global function. This function returns a V5 handler on the CATIXMLDOMDocumentBuilder
interface, which is the main interface for the V5 DOM component. Using
this interface you will be able to create documents (either from
scratch, as here, or by parsing an existing XML file) and save existing
documents to disk. Note that the code above does not specify the CLSID
of the component to use, so the default DOM component (XML4C3) will be
used. See [3] and [4] if you want to
use another V5 DOM component.
[Top]
... CATIDOMImplementation_var implementation; hr = builder->GetDOMImplementation(implementation); ... |
To create document types and documents, one uses an object, which
implements the CATIDOMImplementation interface. This object is
obtained from the CATIXMLDOMDocumentBuilder by invoking its GetDOMImplementation
method.
[Top]
... CATIDOMDocumentType_var docType; hr = implementation->CreateDocumentType("car", "", "automotive.dtd", docType); ... CATIDOMDocument_var document; hr = implementation->CreateDocument("", "car", docType, document); ... |
The CATIDOMImplementation interface acts as a factory to
create DOM document types and DOM documents. The CreateDocumentType
creates a new document type declaration and accepts the following
parameters:
"car" |
The name of the root element |
"" |
A public id (not used here) |
"automotive.dtd" |
The name of an external file, which contains all the grammatical constructs |
docType |
the resulting document type returned by reference. |
Note that the CreateDocumentType
method only creates the
document type declaration (ie: the line <!DOCTYPE car SYSTEM
"automotive.dtd">)
, not the external DTD file. Since such a file
is not in XML, it is usually created by other means (a text editor or a
more powerful tool) by the developer in charge of creating the grammar
to describe the targeted domain.
The CreateDocument
method creates a new DOM document. It
accepts the following parameters:
"" |
The namespace of root element |
"car" |
The name of the root element |
docType |
The previously created document type. Passing NULL_var
will cause the document type declaration to be omitted in the
generated XML |
document |
the resulting document returned by reference. |
[Top]
... CATIDOMElement_var car; hr = document->CreateElement("car", car); ... CATIDOMElement_var seat; hr = document->CreateElement("part", seat); ... CATIDOMElement_var engine; hr = document->CreateElement("part", engine); ... hr = engine->SetAttribute("name", "engine"); ... hr = engine->SetAttribute("quantity", "1"); ... CATIDOMText_var engineText; hr = document->CreateTextNode("low consumption engine", engineText); ... CATIDOMComment_var comment; hr = document->CreateComment("list of parts for a convertible car", comment); ... |
The CATIDOMDocument interface acts as a factory to create
all the other XML constructs: elements, text nodes, comments, processing
instructions, etc. Elements can be created with the CreateElement
method; text nodes can be created with the CreateText
method;
comments can be created with the CreateComment
method. Each of
these method returns a object, which implements the corresponding DOM
interface (CATIDOMElement, CATIDOMText, CATIDOMComment).
Using these interfaces, the created DOM nodes can then be further
customized: for instance, calling the SetAttribute
method of a
CATIDOMElement lets you set the value of this element's
attributes.
Note that the DOM nodes, which we have created are just isolated building blocks at this stage. They are not yet attached to the DOM document. If we were to save the document at this point, they would not appear in the resulting XML file, since only the nodes, which are children of the document are actually saved.
[Top]
... hr = document->AppendChild(car); ... hr = car->AppendChild(seat); ... hr = car->AppendChild(engine); ... hr = engine->AppendChild(engineText); ... hr = car->InsertBefore(comment, seat); ... |
In this step, we assemble the building blocks we have created in the
previous step to create a DOM tree. The DOM API views XML documents as a
tree of XML nodes. The root element of the XML document corresponds to
the root of the DOM tree. The sub-elements of the root element are the
children of this root node. We use the AppendChild
and InsertBefore
methods to nest the nodes with respect to one another.
Note that the DOM API will perform tests on the fly to ensure that the resulting document is well-formed. If you try to perform the following operation, you will get a FAILED HRESULT with an associated CATDOMException warning you that the operation is impossible since it would break the DOM hierarchy.
hr = comment->AppendChild(seat); // Will return E_FAIL since this would result in a not well-formed document |
However, DOM does not guarantee validity. Nothing will prevent you to
perform the following operation, which will result in a well-formed, but
invalid XML document (a part element cannot contain car element as per
the automotive.dtd
grammar).
hr = seat->AppendChild(car); // Will return S_OK since DOM does not verify validity. |
[Top]
... hr = builder->WriteToFile(document, outputFile); ... |
To create the XML document, which corresponds to the DOM tree, call
the WriteToFile
method. It takes as a parameter the path of the
XML document to be created.
By default, the resulting document will use the default (UTF-8) encoding. Note that the "encoding" attribute will not be specified in the XML declaration. However, the XML specification indicates that if the encoding attribute is not specified, XML parsers should consider the document uses the UTF-8 encoding. See [2] and [4] for more information on XML encodings.
[Top]
The XMLParser framework uses the HRESULT / CATError mechanism to
manage errors. Make sure to use the CATError::CATGetLastError
to obtain all the available error diagnostics when using XMLParser. More
information about V5 error management is available here [2]
and [4].
[Top]
This use case shows you how to create XML documents from scratch using the DOM API.
[Top]
[1] | Building and Launching a CAA V5 Use Case |
[2] | Managing Errors Using HRESULT |
[3] | Using XML in V5 |
[4] | XML Tips and Tricks |
[Top] |
Version: 1 [May 2005] | Document created |
[Top] |
Copyright © 2005, Dassault Systèmes. All rights reserved.