As a first example, consider the following very simple XML instance data (source):
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
standalone
=
"yes"
?>
<root>
<element>
<child
number
=
"1"
>
This is child number 1
</child>
<child
number
=
"2"
>
This is child number 2
</child>
</element>
</root>
Assuming XCG.XML is in the same directory, then executing the command
xcg -g ex1.xml
will produce the following files, within the ex1 directory:
- Root.hpp
-
Declaration of the Root, Element, and Child classes
- Root.inl
-
Inline implementations of the simple methods of the Root, Element, and Child
classes. For example, the default constructor, attribute accessor functions,
etc.
- Root.cpp
-
Implementations of all methods for the Root, Element, and Child classes that
are are too complex to make inline.
The c++ code that was generated has the following features:
-
Uses libxml2 for reading, writing, and validating an XML instace. If zlib and
iconv are provided, libxml2 provides the abilities to translate between
encodings and compress the data.
-
All generated code is contained within a namespace, all lowercase, of the root
element name. In this case, the namespace is "root".
-
Provides classes to encapsulate each element. In this case the classes created
are "Root", "Element", and "Child". Note that the class names start with
capital letters. Each class has the following abilites:
-
Read or write itself to a file, in XML format
-
Read or write itself to a libxml2 document
-
Provides members for accessing element attributes
-
Provides members for accessing arrays of child elements
-
Provide members for accessing the value of the element
-
Copy constructor, and operator=
-
Failures and unexpected situations are communicated via std::runtime_error
To read an instance, just construct the root element class and pass the path to
the file, like this:
root::Root r("data.xml");
If no exceptions are thrown, then the file was read and parsed correctly.
To walk the <child> elements, you can use std::for_each if you don't need
to modify the child elements, or walk the list directly if you do. Here is an
example of using std::for_each to dump the objects:
void
dump(
const
root::Child& c);
std::for_each(r.children().begin(), r.children().end(), c);