To illustrate this idea, let's look at the data
structure, using Data::Dumper, a module that
serializes data structures. Just add these lines at the end of the
program:
use Data::Dumper;
print Dumper( $tree );
And here's the output:
$tree = {
'font' => {
'size' => '14',
'name' => 'Times New Roman',
'role' => 'default'
},
'window' => {
'locx' => '100',
'locy' => '120',
'height' => '352',
'width' => '417'
}
};
The $tree variable represents the root element of
the tree, <preferences>. Each entry in the
hash it points to represents its child elements,
<font> and
<window>, accessible by their types. The
entries point to hashes representing the third tier of elements.
Finally, the values of these hash items are strings, the text found
in the actual elements from the file. The whole document is
accessible with a simple string of hash references.
This example was not very complex. Much of the success of
XML::Simple's interface is that
it relies on the XML to be simple. Looking back at our datafile,
you'll note that no sibling elements have the same
name. Identical names would be impossible to encode with hashes
alone.
Example 6-3. A trickier program datafile
<preferences>
<font role="console">
<size>9</size>
<fname>Courier</fname>
</font>
<font role="default">
<fname>Times New Roman</fname>
<size>14</size>
</font>
<font role="titles">
<size>10</size>
<fname>Helvetica</fname>
</font>
</preferences>
We've thrown XML::Simple a curve
ball. There are now three <font> elements in
a row. How will XML::Simple encode that? Dumping
the data structure gives us this output:
$tree = {
'font' => [
{
'fname' => 'Courier',
'size' => '9',
'role' => 'console'
},
{
'fname' => 'Times New Roman',
'size' => '14',
'role' => 'default'
},
{
'fname' => 'Helvetica',
'size' => '10',
'role' => 'titles'
}
]
};
Now the font entry's value is a
reference to a list of hashes, each modeling one of the
<font> elements. To select a font, you must
iterate through the list until you find the one you want. This
iteration clearly takes care of the like-named sibling problem.
This new datafile also adds attributes to some elements. These
attributes have been incorporated into the structure as if they were
child elements of their host elements. Name clashes between
attributes and child elements are possible, but this potential
problem is resolved the same way as like-named sibling elements.
It's convenient this way, as long as you
don't mind if elements and attributes are treated
the same.
We know how to input XML documents to our program, but what about
writing files? XML::Simple also has a method that
outputs XML documents, XML_Out( ). You can
either modify an existing structure or create a new document from
scratch by building a data structure like the ones listed above and
then passing it to the XML_Out( ) method.