File Coverage

blib/lib/XML/DOM2/DOM/Document.pm
Criterion Covered Total %
statement 69 128 53.9
branch 17 50 34.0
condition 4 17 23.5
subroutine 15 28 53.5
pod 22 22 100.0
total 127 245 51.8


line stmt bran cond sub pod time code
1             package XML::DOM2::DOM::Document;
2              
3 3     3   21 use strict;
  3         6  
  3         96  
4 3     3   17 use warnings;
  3         7  
  3         77  
5              
6             =head1 NAME
7              
8             XML::DOM2::DOM::Document
9              
10             =head1 DESCRIPTION
11              
12             Base class for document objects, extends the DOM with document specific methods.
13              
14             =head1 METHODS
15              
16             =cut
17              
18 3     3   2245 use XML::DOM2::Element::DocumentType;
  3         8  
  3         86  
19 3     3   1683 use XML::DOM2::Attribute::Namespace;
  3         11  
  3         103  
20 3     3   19 use XML::DOM2;
  3         7  
  3         65  
21 3     3   17 use Carp;
  3         5  
  3         5836  
22              
23             =head2 $class->createDocumentType( $qualifiedName, $publicId, $systemId, $dtd )
24              
25             Create a new XML Document Type.
26              
27             =cut
28             sub createDocumentType
29             {
30 2     2 1 8 my ($self, $qualifiedName, $publicId, $systemId, $dtd) = @_;
31 2         22 my $doctype = XML::DOM2::Element::DocumentType->new(
32             name => $qualifiedName,
33             publicid => $publicId,
34             systemid => $systemId,
35             dtd => $dtd,
36             );
37 2         16 return $doctype;
38             }
39              
40             =head2 $class->createDocument( $namespaceURI, $qualifiedName, $doctype )
41              
42             Creates a new XML Document.
43              
44             =cut
45             sub createDocument
46             {
47 2     2 1 8 my ($proto, $namespaceURI, $qualifiedName, $doctype) = @_;
48 2   33     14 my $class = ref $proto || $proto;
49 2   33     228 $doctype ||= XML::DOM2->createDocumentType;
50 2         14 my $document = $class->new(
51             namespace => $namespaceURI,
52             name => $qualifiedName,
53             doctype => $doctype,
54             );
55 2         13 $doctype->ownerDocument($document);
56 2         8 return $document;
57             }
58              
59             =head2 $document->documentElement()
60              
61             Returns the main document as an element! it's no longer a document object.
62              
63             =cut
64             sub documentElement
65             {
66 3     3 1 8 my ($self, $setObj) = @_;
67 3 100       16 if(not $self->{'element'}) {
68 2 50       7 if($setObj) {
69 2 50       32 confess "New Document element has no tag name" if not $setObj->localName;
70 2         7 $self->{'element'} = $setObj;
71 2 50       45 if(ref($setObj) eq 'XML::DOM2::Element::Document') {
72 2         9 $self->{'fragment'} = 1;
73             }
74             } else {
75 0         0 $self->{'element'} = $self->createElement(
76             '#document',
77             document => $self,
78             documentTag => $self->_document_name
79             );
80 0 0       0 if($self->{'namespace'}) {
81 0         0 $self->{'element'}->setAttribute( 'xmlns', $self->{'namespace'} );
82             }
83             }
84             }
85 3         21 return $self->{'element'};
86             }
87              
88             =head2 $document->documentType()
89              
90             Returns a document type object for this document.
91              
92             =cut
93             sub documentType
94             {
95 1     1 1 2 my ($self) = @_;
96             # if(not $self->{'doctype'}) {
97             # $self->{'doctype'} = $self->createDocumentType();
98             # }
99 1         4 return $self->{'doctype'};
100             }
101              
102             =head2 $document->addId( $id, $element )
103              
104             Adds an id of an element, used internaly.
105              
106             =cut
107             sub addId
108             {
109 2     2 1 6 my ($self, $id, $tag) = @_;
110 2 50       10 if(not defined($self->{'idlist'})) {
111 2         9 $self->{'idlist'} = {};
112             }
113 2 50       8 if(not defined($self->{'idlist'}->{$id})) {
114 2         6 $self->{'idlist'}->{$id} = $tag;
115 2         10 return 1;
116             }
117 0         0 return undef;
118             }
119              
120             =head2 $document->removeId( $id )
121              
122             Removes an id of an element, used internaly.
123              
124             =cut
125             sub removeId
126             {
127 0     0 1 0 my ($self, $id) = @_;
128 0         0 return delete($self->{'idlist'}->{$id});
129             }
130              
131             =head2 $document->getElementById( $id )
132              
133             Returns the element with that id in this document.
134              
135             =cut
136             sub getElementById
137             {
138 2     2 1 17 my ($self, $id)=@_;
139 2 50       6 return undef unless defined($id);
140 2         4 my $idlist = $self->{'idlist'};
141 2 100       8 if (exists $idlist->{$id}) {
142 1         4 return $idlist->{$id};
143             }
144 1         3 return undef;
145             }
146              
147             =head2 $document->addElement( $element )
148              
149             Adds an element to the elements list, used internaly.
150              
151             =cut
152             sub addElement
153             {
154 18     18 1 26 my ($self, $tag) = @_;
155 18         57 my $name = $tag->localName;
156 18 100       126 if(not defined($self->{'elist'})) {
157 2         6 $self->{'elist'} = {};
158             }
159 18 100       57 if(not defined($self->{'elist'}->{$name})) {
160 14         47 $self->{'elist'}->{$name} = [];
161             }
162 18         24 $tag->{'tagindex'} = @{$self->{'elist'}->{$name}};
  18         55  
163 18         21 push @{$self->{'elist'}->{$name}}, $tag;
  18         48  
164 18         51 return 1;
165             }
166              
167             =head2 $document->removeElement( $element )
168              
169             Remove the specified element from the elements list, used internaly.
170              
171             =cut
172             sub removeElement
173             {
174 0     0 1 0 my ($self, $tag) = @_;
175 0         0 my $name = $tag->getElementName;
176 0         0 splice @{$self->{'elist'}->{$name}}, $tag->{'tagindex'}, 1;
  0         0  
177             # Remove the elist name if no nodes;
178             # this keeps getElementNames function consistant
179 0 0       0 delete($self->{'elist'}->{$name}) unless @{$self->{'elist'}->{$name}};
  0         0  
180             }
181              
182             =head2 $document->getElements( $type )
183              
184             =head2 $document->getElementsByType( $type )
185              
186             =head2 $document->getElementsByName( $type )
187              
188             Get all elements of the specified type/tagName; if none is specified, get all elements in document.
189              
190             =cut
191             sub getElements
192             {
193 0     0 1 0 my ($self, $element) = @_;
194 0 0       0 return undef unless exists $self->{'elist'};
195              
196 0         0 my $elist = $self->{'elist'};
197 0 0       0 if (defined $element) {
198 0 0       0 if (exists $elist->{$element}) {
199 0 0       0 return wantarray?@{$elist->{$element}}:
  0         0  
200             $elist->{$element};
201             }
202 0 0       0 return wantarray?():undef;
203             } else {
204             # Return all elements for all types
205 0         0 my @elements;
206 0         0 foreach my $element_type (keys %$elist) {
207 0         0 push @elements,@{$elist->{$element_type}};
  0         0  
208             }
209 0 0       0 return wantarray?@elements:\@elements;
210             }
211             }
212             *getElementsByType=\&getElements;
213             *getElementsByName=\&getElements;
214              
215             =head2 $document->getElementNames()
216              
217             =head2 $document->getElementTypes()
218              
219             Get all the element types in use in the document.
220              
221             =cut
222             sub getElementNames
223             {
224 0     0 1 0 my $self = shift;
225 0         0 my @types = keys %{$self->{'elist'}};
  0         0  
226              
227 0 0       0 return wantarray ? @types : \@types;
228             }
229             *getElementTypes=\&getElementNames;
230              
231             =head2 $document->addDefinition( $def )
232              
233             Add a definition to the document.
234              
235             =cut
236             sub addDefinition
237             {
238 0     0 1 0 my ($self, $object) = @_;
239 0 0       0 $self->{'defs'} = [] if(not $self->{'defs'});
240 0         0 push @{$self->{'defs'}}, $object;
  0         0  
241 0         0 return $self;
242             }
243              
244             =head2 $document->definitions( )
245              
246             Return all definitions in document.
247              
248             =cut
249             sub definitions
250             {
251 0     0 1 0 my ($self) = @_;
252 0   0     0 return $self->{'defs'} || [];
253             }
254              
255             =head2 $document->getNamespace( $uri )
256              
257             Return a namespace based on the uri or prefix.
258              
259             =cut
260             sub getNamespace
261             {
262 2     2 1 5 my ($self, $uri) = @_;
263 2 50       18 $self->{'xmlns'} = {} if not $self->{'xmlns'};
264 2 50 33     18 if($uri eq 'xmlns' and not $self->{'xmlns'}->{'xmlns'}) {
265 2         22 $self->{'xmlns'}->{'xmlns'} = XML::DOM2::Attribute::Namespace->new(
266             owner => $self,
267             name => 'xmlns',
268             prefix => 'xmlns',
269             uri => 'XML Namespace URI'
270             );
271             }
272 2         11 return $self->{'xmlns'}->{$uri};
273             }
274              
275             =head2 $document->createNamespace( $prefix, $uri )
276              
277             Create a new namespace within this document.
278              
279             =cut
280             sub createNamespace
281             {
282 0     0 1 0 my ($self, $prefix, $uri) = @_;
283 0         0 my $xmlns = $self->getNamespace( 'xmlns' );
284 0         0 $self->documentElement->setAttributeNS( $xmlns, $prefix, $uri );
285 0         0 my $ns = $self->documentElement->getAttributeNS( $xmlns, $prefix );
286 0 0       0 if(not $ns) {
287 0         0 carp "Unable to create namespace, no attribute defined";
288             }
289 0         0 return $ns;
290             }
291              
292             =head2 $document->addNamespace( $namespace )
293              
294             Add namespace to this document.
295              
296             =cut
297             sub addNamespace
298             {
299 0     0 1 0 my ($self, $namespace) = @_;
300 0         0 $self->{'xmlns'}->{$namespace->ns_prefix} = $namespace;
301 0         0 $self->{'xmlns'}->{$namespace->ns_uri} = $namespace;
302             }
303              
304             =head2 $document->removeNamespace( $namespace )
305              
306             Remove a namespace from this document.
307              
308             =cut
309             sub removeNamespace
310             {
311 0     0 1 0 my ($self, $namespace) = @_;
312 0         0 delete($self->{'xmlns'}->{$namespace->ns_prefix});
313 0         0 delete($self->{'xmlns'}->{$namespace->ns_uri});
314             }
315              
316             =head2 $document->createElement( $name, %options )
317              
318             Creates a new element of type name.
319              
320             =cut
321             sub createElement
322             {
323 20     20 1 59 my ($self, $name, %opts) = @_;
324 20 50 33     116 croak "Unable to create element without a name" if not defined($name) or $name eq '';
325 20         79 my $element = $self->_element_handle( $name, %opts );
326 20         186 return $element;
327             }
328              
329             =head2 $document->createElementNS( $namespace, $name, %options )
330              
331             Create an element in a namespace.
332              
333             =cut
334             sub createElementNS
335             {
336 0     0 1   my ($self, $ns, $name, %opts) = @_;
337 0 0 0       croak "Unable to create element without a name" if not defined($name) or $name eq '';
338 0           my $element = $self->_element_handle(
339             $name,
340             namespace => $ns,
341             name => $name,
342             %opts,
343             );
344 0           return $element;
345             }
346              
347             =head2 $document->createTextNode( $data )
348              
349             Create a textnode element.
350              
351             =cut
352             sub createTextNode
353             {
354 0     0 1   my ($self, $data) = @_;
355 0           return $self->_element_handle( '#cdata-entity', notag => 1 );
356             }
357              
358             =head2 $document->createComment( $data )
359              
360             Create a comment element
361              
362             =cut
363             sub createComment
364             {
365 0     0 1   my ($self, $data) = @_;
366 0           return $self->_element_handle( '#comment', text => $data );
367             }
368              
369             =head2 $document->createCDATASection( $data )
370              
371             create a CDATA element.
372              
373             =cut
374             sub createCDATASection
375             {
376 0     0 1   my ($self, $data) = @_;
377 0           return $self->_element_handle( '#cdata-entity', notag => 0 );
378             }
379              
380             =head1 COPYRIGHT
381              
382             Martin Owens, doctormo@cpan.org
383              
384             =head1 SEE ALSO
385              
386             L
387              
388             =cut
389             1;