File Coverage

blib/lib/XML/EasySQL/XMLobj.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             XML::EasySQL::XMLobj - Fork of Robert Hanson's killer XML::EasyOBJ
4             module, which offers Easy XML object navigation
5              
6             =head1 VERSION
7              
8             Version 1.2
9              
10             =head1 SYNOPSIS
11              
12             XML::EasySQL::XMLobj is a fork of Robert Hanson's XML::EasyOBJ module.
13             The goal of the fork was to simplify inheritance issues. However, easy
14             inheritance comes at a cost: class method names can no longer be
15             dynamically renamed. If inheritance isn't needed and you desire
16             the dynamic method renaming feature, I suggest you download Hanson's
17             original XML::EasyOBJ module from CPAN.
18              
19             NOTE: The rest of the documentation for this module was written by
20             Robert Hanson
21              
22             -Curtis Lee Fulton
23              
24             # open exisiting file
25             my $doc = new XML::EasySQL::XMLobj({type => 'file', param => 'my_xml_document.xml'});
26              
27             # create object from XML string
28             my $doc = new XML::EasySQL::XMLobj({type => 'string', -param => $xml_source});
29              
30             # create new file
31             my $doc = new XML::EasySQL::XMLobj({type => 'new', param => 'root_tag'});
32              
33             # read from document
34             my $text = $doc->root->some_element($index)->getString;
35             my $attr = $doc->root->some_element($index)->getAttr('foo');
36             my $element = $doc->root->some_element($index);
37             my @elements = $doc->root->some_element;
38              
39             # first "some_element" element
40             my $elements = $doc->root->some_element;
41             # list of "some_element" elements
42             my @elements = $doc->root->some_element;
43              
44             # write to document
45             $doc->root->an_element->setString('some string')
46             $doc->root->an_element->addString('some string')
47             $doc->root->an_element->setAttr('attrname', 'val')
48             $doc->root->an_element->setAttr('attr1' => 'val', 'attr2' => 'val2')
49              
50             # access elements with non-name chars and the underlying DOM
51             my $element = $doc->root->getElement('foo-bar')->getElement('bar-none');
52             my $dom = $doc->root->foobar->getDomObj;
53              
54             # get elements without specifying the element name
55             my @elements = $doc->root->getElement();
56             my $sixth_element = $doc->root->getElement('', 5);
57              
58             # remove elements/attrs
59             $doc->root->remElement('tagname', $index);
60             $doc->root->tag_name->remAttr($attr);
61              
62             =head1 DESCRIPTION
63              
64             I wrote XML::EasyOBJ a couple of years ago because it seemed to me
65             that the DOM wasn't very "perlish" and the DOM is difficult for us
66             mere mortals that don't use it on a regular basis. As I only need
67             to process XML on an occasionally I wanted an easy way to do what
68             I needed to do without having to refer back to DOM documentation
69             each time.
70              
71             A quick fact list about XML::EasySQL::XMLobj:
72              
73             * Runs on top of XML::DOM
74             * Allows access to the DOM as needed
75             * Simple routines to reading and writing elements/attributes
76              
77             =head1 REQUIREMENTS
78              
79             XML::EasySQL::XMLobj uses XML::DOM. XML::DOM is available from CPAN (www.cpan.org).
80              
81             =head1 METHODS
82              
83             Below is a description of the class constructor. See XML::EasySQL::XMLobj::Node for the method documentation.
84              
85             =cut
86              
87             package XML::EasySQL::XMLobj;
88              
89 1     1   540 use XML::DOM;
  0            
  0            
90             use strict;
91              
92             use vars qw/$VERSION/;
93             $VERSION = '1.2';
94              
95             =head2 new
96              
97             You can create a new object from an XML file, a string of XML, or
98             a new document. The constructor takes an anon hash with the following
99             keys:
100              
101             =over
102              
103             =item type
104              
105             The type is either "file", "string" or "new". "file" will create
106             the object from a file source, "string" will create the object from
107             a string of XML code, and "new" will create a new document object.
108              
109             =item param
110              
111             This value depends on the -type that is passed to the constructor.
112             If the -type is "file" this will be the filename to open and parse.
113             If -type is "string", this is a string of XML code. If -type is
114             "new", this is the name of the root element.
115              
116             =item class_constructor
117              
118             If you've made a derived class from XML::EasySQL::XMLnode, specify the class
119             name here. It defaults to XML::EasySQL::XMLobj::Node.
120              
121             If you're using constructor_class, any additional keys will be passed on to
122             the XML::EasySQL::XMLobj::Node derived class.
123              
124             Creating an object from an XML file:
125              
126             my $doc = new XML::EasySQL::XMLobj({type => 'file', param => 'my_xml_document.xml'});
127              
128             Creating an object from a string containing the XML source:
129              
130             my $doc = new XML::EasySQL::XMLobj({type => 'string', param => $xml_source});
131              
132             Creating a new XML document by passing the root tag name:
133              
134             my $doc = new XML::EasySQL::XMLobj({type => 'new', param => 'root_tag'});
135              
136             =back
137              
138             =cut
139              
140             sub new {
141             my $proto = shift;
142             my $params = shift;
143             my $class = ref($proto) || $proto;
144             my $self = {};
145              
146             # container for DOM object
147             my $doc = undef;
148              
149             # create DOM from file, param is filename
150             if ( $params->{type} eq 'file' ) {
151             my $parser = new XML::DOM::Parser;
152             $doc = $parser->parsefile( $params->{param} ) || return undef;
153             }
154              
155             # create a new DOM object, param is root element name
156             elsif ( $params->{type} eq 'new' ) {
157             $doc = new XML::DOM::Document();
158             $doc->appendChild( $doc->createElement($params->{param}) );
159             }
160              
161             # create DOM from string
162             elsif ( $params->{type} eq 'string' ) {
163             my $parser = new XML::DOM::Parser;
164             $doc = $parser->parse( $params->{param} ) || return undef;
165             } else {
166             die "bad arguments for __PACKAGE__ constructor\n";
167             }
168              
169             if(!defined $doc) {
170             die "problem creating XML::DOM document. Check your __PACKAGE__ constructor arguments\n";
171             }
172              
173             $self->{doc} = $doc;
174             $self->{ptr} = $doc->getDocumentElement();
175             $self->{constructor_class} = $params->{constructor_class};
176              
177             my %constructor_params_copy = %{$params};
178             delete $constructor_params_copy{type};
179             delete $constructor_params_copy{param};
180             delete $constructor_params_copy{constructor_class};
181              
182             $self->{constructor_params} = \%constructor_params_copy;
183              
184             $self->{root} = undef;
185              
186             bless $self, $class;
187             }
188              
189             =head2 root
190              
191             The root XML::EasySQL::XMLobj::Node object.
192              
193             =cut
194              
195             sub root {
196             my $self = shift;
197             if(!ref $self->{root}) {
198             $self->_root();
199             }
200             return $self->{root};
201             }
202              
203             sub _root {
204             my $self = shift;
205             my $doc = $self->{doc};
206             my $ptr = $self->{ptr};
207              
208             if(defined $self->{constructor_class}) {
209             my %constructor_params_copy = %{$self->{constructor_params}};
210             $constructor_params_copy{doc} = $doc;
211             $constructor_params_copy{ptr} = $ptr;
212             $constructor_params_copy{constructor_params} = $self->{constructor_params};
213             $self->{root} = $self->{constructor_class}->new(\%constructor_params_copy);
214             } else {
215             use XML::EasySQL::XMLobj::Node;
216             $self->{root} = XML::EasySQL::XMLobj::Node->new({doc=>$doc, ptr=>$ptr});
217             }
218             }
219              
220             =head2 constructorParams
221              
222             Returns a hash ref of args. If you're using a derived node class,
223             you can change the args the node constructor gets by modifying this hash.
224              
225             =cut
226              
227             sub constructorParams {
228             my $self = shift;
229             return $self->{constructor_params};
230             }
231              
232             1;
233              
234             =head1 BEGINNER QUICK START GUIDE
235              
236             =head2 Introduction
237              
238             You too can write XML applications, just as long as you understand
239             the basics of XML (elements and attributes). You can learn to write
240             your first program that can read data from an XML file in a mere
241             10 minutes.
242              
243             =head2 Assumptions
244              
245             It is assumed that you are familiar with the structure of the document that
246             you are reading. Next, you must know the basics of perl lists, loops, and
247             how to call a function. You must also have an XML document to read.
248              
249             Simple eh?
250              
251             =head2 Loading the XML document
252              
253             use XML::EasySQL::XMLobj;
254             my $doc = new XML::EasySQL::XMLobj({type=>'file', param=>'my_xml_document.xml'});
255              
256             Replace the string "my_xml_document.xml" with the name of your XML document.
257             If the document is in another directory you will need to specify the path
258             to it as well.
259              
260             The variable $doc is an object, and represents our root XML element in the document.
261              
262             =head2 Reading text with getString
263              
264             Each element becomes an object. So lets assume that the XML page looks like
265             this:
266              
267            
268            
269            
270             field1a
271             field2b
272             field3c
273            
274            
275             field1d
276             field2e
277             field3f
278            
279            
280            
281              
282             As mentioned in he last step, the $doc object is the root
283             element of the XML page. In this case the root element is the "table"
284             element.
285              
286             To read the text of any field is as easy as navigating the XML elements.
287             For example, lets say that we want to retrieve the text "field2e". This
288             text is in the "field2" element of the SECOND "rec2" element, which is
289             in the FIRST "record" element.
290              
291             So the code to print that value it looks like this:
292              
293             print $doc->root->record(0)->rec2(1)->field2->getString;
294              
295             The "getString" method returns the text within an element.
296              
297             We can also break it down like this:
298              
299             # grab the FIRST "record" element (index starts at 0)
300             my $record = $doc->root->record(0);
301              
302             # grab the SECOND "rec2" element within $record
303             my $rec2 = $record->rec2(1);
304              
305             # grab the "field2" element from $rec2
306             # NOTE: If you don't specify an index, the first item
307             # is returned and in this case there is only 1.
308             my $field2 = $rec2->field2;
309              
310             # print the text
311             print $field2->getString;
312              
313             =head2 Reading XML attributes with getAttr
314              
315             Looking at the example in the previous step, can you guess what
316             this code will print?
317              
318             print $doc->root->record(0)->rec2(0)->getAttr('foo');
319             print $doc->root->record(0)->rec2(1)->getAttr('foo');
320              
321             If you couldn't guess, they will print out the value of the "foo"
322             attribute of the first and second rec2 elements.
323              
324             =head2 Looping through elements
325              
326             Lets take our example in the previous step where we printed the
327             attribute values and rewrite it to use a loop. This will allow
328             it to print all of the "foo" attributes no matter how many "rec2"
329             elements we have.
330              
331             foreach my $rec2 ( $doc->root->record(0)->rec2 ) {
332             print $rec2->getAttr('foo');
333             }
334              
335             When we call $doc->record(0)->rec2 this way (i.e. in list context),
336             the module will return a list of "rec2" elements.
337              
338             =head2 That's it!
339              
340             You are now an XML programmer! *start rejoicing now*
341              
342             =head1 PROGRAMMING NOTES
343              
344             Both XML::EasySQL::XMLobj and XML::EasySQL::XMLobj::Node can be
345             used as base classes.
346              
347             When creating a new instance of XML::EasySQL::XMLobj it will return an
348             object reference on success, or die on failure. Besides that,
349             ALL methods will always return a value. This means that if you
350             specify an element that does not exist, it will still return an
351             object reference (and create that element automagically). This
352             is just another way to lower the bar, and make this module easier
353             to use.
354              
355             You will run into problems if you have XML tags which are named
356             after perl's special subroutine names (i.e. "DESTROY", "AUTOLOAD"),
357             or if they are named after subroutines used in the module
358             ( "getString", "getAttr", etc ). You can get around this by using
359             the getElement() method. If you need to rename the methods dynamically,
360             (except AUTOLOAD and DESTROY), try Hanson's original from CPAN.
361              
362             =head1 AUTHOR/COPYRIGHT
363              
364             Copyright (C) 2000-2002 Robert Hanson
365              
366             This library is free software; you can redistribute it and/or modify
367             it under the same terms as Perl itself.
368              
369             Forked by Curtis Lee Fulton 2-29-04.
370              
371             =head1 SEE ALSO
372              
373             XML::DOM
374              
375             XML::EasySQL::XMLobj::Node
376              
377             =cut
378              
379              
380