📄 ch06_02.htm
字号:
<html><head><title>XML::Simple (Perl and XML)</title><link rel="stylesheet" type="text/css" href="../style/style1.css" /><meta name="DC.Creator" content="Erik T. Ray and Jason McIntosh" /><meta name="DC.Format" content="text/xml" scheme="MIME" /><meta name="DC.Language" content="en-US" /><meta name="DC.Publisher" content="O'Reilly & Associates, Inc." /><meta name="DC.Source" scheme="ISBN" content="059600205XL" /><meta name="DC.Subject.Keyword" content="stuff" /><meta name="DC.Title" content="Perl and XML" /><meta name="DC.Type" content="Text.Monograph" /></head><body bgcolor="#ffffff"><img alt="Book Home" border="0" src="gifs/smbanner.gif" usemap="#banner-map" /><map name="banner-map"><area shape="rect" coords="1,-2,616,66" href="index.htm" alt="Perl & XML" /><area shape="rect" coords="629,-11,726,25" href="jobjects/fsearch.htm" alt="Search this book" /></map><div class="navbar"><table width="684" border="0"><tr><td align="left" valign="top" width="228"><a href="ch06_01.htm"><img alt="Previous" border="0" src="../gifs/txtpreva.gif" /></a></td><td align="center" valign="top" width="228" /><td align="right" valign="top" width="228"><a href="ch06_03.htm"><img alt="Next" border="0" src="../gifs/txtnexta.gif" /></a></td></tr></table></div><h2 class="sect1">6.2. XML::Simple</h2><p>The <a name="INDEX-493" /> <a name="INDEX-494" />simplest tree model can be found in Grant<a name="INDEX-495" />McLean's module<tt class="literal">XML::Simple</tt>. It's designed tofacilitate the job of reading and saving datafiles. The programmerdoesn't have to know much about XML andparsers -- only how to access arrays and hashes, the datastructures used to store a document.</p><p><a href="ch06_02.htm#perlxml-CHP-6-EX-1">Example 6-1</a> shows a simple datafile that a programmight use to store information.</p><a name="perlxml-CHP-6-EX-1" /><div class="example"><h4 class="objtitle">Example 6-1. A program datafile </h4><blockquote><pre class="code"><preferences> <font role="default"> <name>Times New Roman</name> <size>14</size> </font> <window> <height>352</height> <width>417</width> <locx>100</locx> <locy>120</locy> </window></preferences></pre></blockquote></div><p><tt class="literal">XML::Simple</tt> makes accessing information in thedatafile remarkably easy. <a href="ch06_02.htm#perlxml-CHP-6-EX-2">Example 6-2</a> extractsdefault font information from it.</p><a name="perlxml-CHP-6-EX-2" /><div class="example"><h4 class="objtitle">Example 6-2. Program to extract font information </h4><blockquote><pre class="code">use XML::Simple;my $simple = XML::Simple->new( ); # initialize the objectmy $tree = $simple->XMLin( './data.xml' ); # read, store document# test access to the treeprint "The user prefers the font " . $tree->{ font }->{ name } . " at " . $tree->{ font }->{ size } . " points.\n";</pre></blockquote></div><p>First we initialize an <tt class="literal">XML::Simple</tt> object, then wetrigger the parser with a call to its <tt class="literal">XMLin()</tt><a name="INDEX-496" />method. This step returns a reference to the root of the tree, whichis a hierarchical set of hashes. Element names provide keys to thehashes, whose values are either strings or references to otherelement hashes. Thus, we have a clear and concise way to accesspoints deep in the document.</p><p>To illustrate this idea, let's look at the datastructure, using <tt class="literal">Data::Dumper</tt>, a module thatserializes data structures. Just add these lines at the end of theprogram:</p><blockquote><pre class="code">use Data::Dumper;print Dumper( $tree );</pre></blockquote><p>And here's the output: </p><blockquote><pre class="code">$tree = { 'font' => { 'size' => '14', 'name' => 'Times New Roman', 'role' => 'default' }, 'window' => { 'locx' => '100', 'locy' => '120', 'height' => '352', 'width' => '417' } };</pre></blockquote><p>The <tt class="literal">$tree</tt> variable represents the root element ofthe tree, <tt class="literal"><preferences></tt>. Each entry in thehash it points to represents its child elements,<tt class="literal"><font></tt> and<tt class="literal"><window></tt>, accessible by their types. Theentries point to hashes representing the third tier of elements.Finally, the values of these hash items are strings, the text foundin the actual elements from the file. The whole document isaccessible with a simple string of hash references.</p><p>This example was not very complex. Much of the success of<tt class="literal">XML::Simple</tt>'s interface is thatit relies on the XML to be simple. Looking back at our datafile,you'll note that no sibling elements have the samename. Identical names would be impossible to encode with hashesalone.</p><p>Fortunately, <tt class="literal">XML::Simple</tt> has an answer. If anelement has two or more child elements with the same name, it uses alist to contain all the like-named children in a group. Consider therevised datafile in <a href="ch06_02.htm#perlxml-CHP-6-EX-3">Example 6-3</a>.</p><a name="perlxml-CHP-6-EX-3" /><div class="example"><h4 class="objtitle">Example 6-3. A trickier program datafile </h4><blockquote><pre class="code"><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></pre></blockquote></div><p>We've thrown <tt class="literal">XML::Simple</tt> a curveball. There are now three <tt class="literal"><font></tt> elements ina row. How will <tt class="literal">XML::Simple</tt> encode that? Dumpingthe data structure gives us this output:</p><blockquote><pre class="code">$tree = { 'font' => [ { 'fname' => 'Courier', 'size' => '9', 'role' => 'console' }, { 'fname' => 'Times New Roman', 'size' => '14', 'role' => 'default' }, { 'fname' => 'Helvetica', 'size' => '10', 'role' => 'titles' } ] };</pre></blockquote><p>Now the <tt class="literal">font</tt> entry's value is areference to a list of hashes, each modeling one of the<tt class="literal"><font></tt> elements. To select a font, you mustiterate through the list until you find the one you want. Thisiteration clearly takes care of the like-named sibling problem.</p><p>This new datafile also adds attributes to some elements. Theseattributes have been incorporated into the structure as if they werechild elements of their host elements. Name clashes betweenattributes and child elements are possible, but this potentialproblem is resolved the same way as like-named sibling elements.It's convenient this way, as long as youdon't mind if elements and attributes are treatedthe same.</p><p>We know how to input XML documents to our program, but what aboutwriting files? <tt class="literal">XML::Simple</tt> also has a method thatoutputs XML documents, <tt class="literal">XML_Out( )</tt>. You caneither modify an existing structure or create a new document fromscratch by building a data structure like the ones listed above andthen passing it to the <tt class="literal">XML_Out( )</tt> method.</p><p>Our conclusion? <tt class="literal">XML::Simple</tt> works well with simpleXML documents, but runs into trouble with more complex markup. Itcan't handle elements with both text and elements aschildren (mixed content). It doesn't pay attentionto node types other than elements, attributes, and text (likeprocessing instructions or CDATA sections). Because hashesdon't preserve the order of items, the sequence ofelements may be scrambled. If none of these problems matters to you,then use <tt class="literal">XML::Simple</tt>. It will serve your<a name="INDEX-497" /> <a name="INDEX-498" /> needs well,minimizing the pain of XML markup and keeping your data accessible.</p><hr width="684" align="left" /><div class="navbar"><table width="684" border="0"><tr><td align="left" valign="top" width="228"><a href="ch06_01.htm"><img alt="Previous" border="0" src="../gifs/txtpreva.gif" /></a></td><td align="center" valign="top" width="228"><a href="index.htm"><img alt="Home" border="0" src="../gifs/txthome.gif" /></a></td><td align="right" valign="top" width="228"><a href="ch06_03.htm"><img alt="Next" border="0" src="../gifs/txtnexta.gif" /></a></td></tr><tr><td align="left" valign="top" width="228">6. Tree Processing</td><td align="center" valign="top" width="228"><a href="index/index.htm"><img alt="Book Index" border="0" src="../gifs/index.gif" /></a></td><td align="right" valign="top" width="228">6.3. XML::Parser's Tree Mode</td></tr></table></div><hr width="684" align="left" /><img alt="Library Navigation Links" border="0" src="../gifs/navbar.gif" usemap="#library-map" /><p><p><font size="-1"><a href="copyrght.htm">Copyright © 2002</a> O'Reilly & Associates. All rights reserved.</font></p><map name="library-map"><area shape="rect" coords="1,0,85,94" href="../index.htm"><area shape="rect" coords="86,1,178,103" href="../lwp/index.htm"><area shape="rect" coords="180,0,265,103" href="../lperl/index.htm"><area shape="rect" coords="267,0,353,105" href="../perlnut/index.htm"><area shape="rect" coords="354,1,446,115" href="../prog/index.htm"><area shape="rect" coords="448,0,526,132" href="../tk/index.htm"><area shape="rect" coords="528,1,615,119" href="../cookbook/index.htm"><area shape="rect" coords="617,0,690,135" href="../pxml/index.htm"></map></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -