File Coverage

blib/lib/XML/Mini/Element.pm
Criterion Covered Total %
statement 305 432 70.6
branch 97 194 50.0
condition 27 49 55.1
subroutine 32 40 80.0
pod 26 31 83.8
total 487 746 65.2


line stmt bran cond sub pod time code
1             package XML::Mini::Element;
2 10     10   54 use strict;
  10         18  
  10         399  
3             $^W = 1;
4              
5 10     10   56 use XML::Mini;
  10         16  
  10         233  
6 10     10   7393 use XML::Mini::TreeComponent;
  10         28  
  10         1592  
7 10     10   7970 use XML::Mini::Element::Comment;
  10         25  
  10         284  
8 10     10   6200 use XML::Mini::Element::DocType;
  10         26  
  10         268  
9 10     10   6062 use XML::Mini::Element::Entity;
  10         26  
  10         298  
10 10     10   6559 use XML::Mini::Element::CData;
  10         28  
  10         339  
11              
12 10     10   59 use vars qw ( $VERSION @ISA );
  10         18  
  10         58468  
13             push @ISA, qw ( XML::Mini::TreeComponent );
14             $VERSION = '1.38';
15              
16             sub new
17             {
18 1113     1113 1 1420 my $class = shift;
19 1113         1630 my $name = shift;
20            
21 1113         1733 my $self = {};
22 1113   33     5576 bless $self, ref $class || $class;
23            
24 1113         2775 $self->{'_attributes'} = {};
25 1113         2070 $self->{'_numChildren'} = 0;
26 1113         1740 $self->{'_numElementChildren'} = 0;
27 1113         2004 $self->{'_children'} = [];
28 1113         1678 $self->{'_avoidLoops'} = $XML::Mini::AvoidLoops;
29            
30 1113 50       1918 if ($name)
31             {
32 1113         2289 $self->name($name);
33             } else {
34 0         0 return XML::Mini->Error("Must pass a name to create a new Element.");
35             }
36              
37 1113         1919 return $self;
38             }
39              
40             sub name
41             {
42 2626     2626 1 7819 my $self = shift;
43 2626         3048 my $name = shift;
44            
45 2626 100       5038 if (defined $name)
46             {
47 1134         2633 $self->{'_name'} = $name;
48             }
49            
50 2626         5603 return $self->{'_name'};
51             }
52              
53             sub attribute
54             {
55 419     419 1 5016 my $self = shift;
56 419   50     907 my $name = shift || return undef;
57 419         506 my $primValue = shift;
58 419         504 my $altValue = shift;
59            
60 419 100       802 my $value = (defined $primValue) ? $primValue : $altValue;
61            
62 419 100       701 if (defined $value)
63             {
64 399         1244 $self->{'_attributes'}->{$name} = $value;
65             } else {
66 20 50       74 $self->{'_attributes'}->{$name} = ''
67             unless (defined $self->{'_attributes'}->{$name});
68             }
69            
70 419 50       1094 if (defined $self->{'_attributes'}->{$name})
71             {
72 419         1266 return $self->{'_attributes'}->{$name};
73             }
74            
75 0         0 return undef;
76             }
77              
78             sub text
79             {
80 27     27 1 363 my $self = shift;
81 27         43 my $primValue = shift;
82 27         34 my $altValue = shift;
83            
84 27 50       56 my $setTo = (defined $primValue) ? $primValue : $altValue;
85            
86 27 50       63 if (defined $setTo)
87             {
88 27         67 $self->createNode($setTo);
89             }
90            
91 27         39 my @contents;
92            
93 27         32 foreach my $child (@{$self->{'_children'}})
  27         63  
94             {
95 28         95 my $value = $child->getValue();
96 28 50       68 if (defined $value)
97             {
98 28         98 push @contents, $value;
99             }
100             }
101            
102 27 50       67 if (scalar @contents)
103             {
104 27         68 my $retStr = join(' ', @contents);
105 27         69 return $retStr;
106             }
107            
108 0         0 return undef;
109             }
110              
111             sub numeric
112             {
113 0     0 1 0 my $self = shift;
114 0         0 my $primValue = shift;
115 0         0 my $altValue = shift;
116            
117 0 0       0 my $setTo = (defined $primValue) ? $primValue : $altValue;
118            
119 0 0       0 if (defined $setTo)
120             {
121 0 0       0 return XML::Mini->Error("Must pass a NUMERIC value to Element::numeric() to set ($setTo)")
122             unless ($setTo =~ m/^\s*[Ee\d\.\+-]+\s*$/);
123            
124 0         0 $self->text($setTo);
125             }
126            
127            
128 0         0 my @contents;
129 0         0 foreach my $child (@{$self->{'_children'}})
  0         0  
130             {
131 0         0 my $value = $child->getValue();
132 0 0       0 if (defined $value)
133             {
134 0 0       0 push @contents, $value if ($value =~ /^\s*[Ee\d\.\+-]+\s*$/);
135             }
136             }
137            
138 0 0       0 if (scalar @contents)
139             {
140 0         0 my $retStr = join(' ', @contents);
141 0         0 return $retStr;
142             }
143            
144 0         0 return undef;
145             }
146              
147             sub comment
148             {
149 2     2 1 3 my $self = shift;
150 2         5 my $contents = shift;
151            
152 2         21 my $newEl = XML::Mini::Element::Comment->new();
153 2         17 $newEl->text($contents);
154            
155 2         7 $self->appendChild($newEl);
156            
157 2         6 return $newEl;
158             }
159              
160             sub header
161             {
162 1     1 1 484 my $self = shift;
163 1         2 my $name = shift;
164 1         2 my $attribs = shift; # optional
165            
166 1 50       4 unless (defined $name)
167             {
168 0         0 return XML::Mini->Error("XML::Mini::Element::header() must pass a NAME to create a new header");
169             }
170            
171 1         13 my $newElement = XML::Mini::Element::Header->new($name);
172 1         5 $self->appendChild($newElement);
173            
174 1         3 return $newElement;
175             }
176              
177              
178             sub docType
179             {
180 0     0 1 0 my $self = shift;
181 0         0 my $definition = shift;
182            
183 0         0 my $newElement = XML::Mini::Element::DocType->new($definition);
184 0         0 $self->appendChild($newElement);
185            
186 0         0 return $newElement;
187             }
188              
189             sub entity
190             {
191 0     0 1 0 my $self = shift;
192 0         0 my $name = shift;
193 0         0 my $value = shift;
194            
195 0         0 my $newElement = XML::Mini::Element::Entity->new($name, $value);
196 0         0 $self->appendChild($newElement);
197            
198 0         0 return $newElement;
199             }
200              
201             sub cdata
202             {
203 0     0 1 0 my $self = shift;
204 0         0 my $contents = shift;
205 0         0 my $newElement = XML::Mini::Element::CData->new($contents);
206 0         0 $self->appendChild($newElement);
207            
208 0         0 return $newElement;
209             }
210              
211             # Note: the seperator parameter remains officially undocumented
212             # since I'm not sure it will remain part of the API
213             sub getValue {
214 7     7 1 543 my $self = shift;
215 7   50     50 my $seperator = shift || ' ';
216            
217 7         11 my @valArray;
218 7         13 my $retStr = '';
219            
220 7         12 foreach my $child ( @{$self->{'_children'}})
  7         23  
221             {
222 7         26 my $value = $child->getValue();
223 7 50       23 if (defined $value)
224             {
225 7         25 push @valArray , $value;
226             }
227             }
228            
229 7 50       23 if (scalar @valArray)
230             {
231 7         20 $retStr = join($seperator, @valArray);
232             }
233            
234 7         23 return $retStr;
235             }
236              
237             sub getElement {
238 119     119 1 309 my $self = shift;
239 119         168 my $name = shift;
240 119   100     489 my $elementNumber = shift || 1;
241            
242 119 50       215 return XML::Mini->Error("Element::getElement() Must Pass Element name.")
243             unless defined ($name);
244            
245 119 50       219 if ($XML::Mini::Debug)
246             {
247 0         0 XML::Mini->Log("Element::getElement() called for $name on " . $self->{'_name'} );
248             }
249            
250            
251             ########## getElement needs to search the calling element's children ONLY
252             ########## or else it is impossible to retrieve the nested element of the same name:
253             ##########
254             ##########
255             ########## The second nested element is inaccessible if we return $self...
256             ##########
257             ##########
258             #if ($XML::Mini::CaseSensitive)
259             #{
260             #return $self if ($self->{'_name'} =~ m/^$name$/);
261             #} else {
262             #return $self if ($self->{'_name'} =~ m/^$name$/i);
263             #}
264            
265 119 100       255 return undef unless $self->{'_numChildren'};
266            
267 114         129 my $foundCount = 0;
268             #* Try each child (immediate children take priority) *
269 114         282 for (my $i = 0; $i < $self->{'_numChildren'}; $i++)
270             {
271 142         360 my $childname = $self->{'_children'}->[$i]->name();
272 142 100       384 if ($childname)
273             {
274 140 50       219 if ($XML::Mini::CaseSensitive)
275             {
276 0 0       0 if ($name =~ m/^$childname$/)
277             {
278 0         0 $foundCount++;
279 0 0       0 return $self->{'_children'}->[$i] if ($foundCount == $elementNumber);
280             }
281             } else {
282 140 100       973 if ($name =~ m/^$childname$/i)
283             {
284 114         115 $foundCount++;
285 114 100       472 return $self->{'_children'}->[$i] if ($foundCount == $elementNumber);
286             }
287            
288             }
289            
290             } #/* end if child has a name */
291            
292             } #/* end loop over all my children */
293            
294             #/* Now, Use beautiful recursion, daniel san */
295 6         20 for (my $i = 0; $i < $self->{'_numChildren'}; $i++)
296             {
297 13         82 my $theelement = $self->{'_children'}->[$i]->getElement($name, $elementNumber);
298 13 100       42 if ($theelement)
299             {
300            
301 4 50       10 XML::Mini->Log("Element::getElement() returning element " . $theelement->name())
302             if ($XML::Mini::Debug);
303            
304 4         11 return $theelement;
305             }
306             }
307            
308             #/* Not found */
309 2         5 return undef;
310             }
311              
312             sub getElementByPath
313             {
314 6     6 1 31 my $self = shift;
315 6   50     51 my $path = shift || return undef;
316 6         14 my @elementNumbers = @_;
317            
318 6         74 my @names = split ("/", $path);
319 6         18 my $element = $self;
320 6         13 my $position = 0;
321 6         15 foreach my $elementName (@names)
322             {
323 101 50       193 next unless ($elementName);
324 101 50       166 if ($element) #/* Make sure we didn't hit a dead end */
325             {
326             #/* Ask this element to get the next child in path */
327 101         266 $element = $element->getElement($elementName, $elementNumbers[$position++]);
328             }
329             }
330 6         44 return $element;
331             } #/* end method getElementByPath */
332              
333              
334             sub numChildren
335             {
336 17     17 0 502 my $self = shift;
337 17         35 my $named = shift; # optionally only count elements named 'named'
338 17 50       65 unless (defined $named)
339             {
340 17         115 return $self->{'_numElementChildren'};
341             }
342 0         0 my $allkids = $self->getAllChildren($named);
343 0         0 return scalar @{$allkids};
  0         0  
344             }
345              
346             sub getAllChildren
347             {
348 2     2 1 393 my $self = shift;
349 2         6 my $name = shift; # optionally only children with this name
350            
351            
352 2         4 my @returnChildren;
353 2         11 for (my $i=0; $i < $self->{'_numChildren'}; $i++)
354             {
355 46 50       98 if ($self->isElement($self->{'_children'}->[$i]))
356             {
357 46         97 my $childName = $self->{'_children'}->[$i]->name();
358             # return only Element and derivatives children
359 46 100       90 if (defined $name)
360             {
361 26 50       35 if ($XML::Mini::CaseSensitive)
362             {
363 0 0       0 push @returnChildren, $self->{'_children'}->[$i]
364             if ($name =~ /^$childName$/);
365             } else {
366             # case insensitive
367 26 100       142 push @returnChildren, $self->{'_children'}->[$i]
368             if ($name =~ /^$childName$/i);
369             }
370             } else {
371             # no name set, all children returned
372 20         73 push @returnChildren, $self->{'_children'}->[$i];
373             } # end if name
374             } # end if element
375             } # end loop over all children
376 2         8 return \@returnChildren;
377             }
378              
379             sub isElement
380             {
381 1382     1382 0 1588 my $self = shift;
382 1382   66     2804 my $element = shift || $self;
383 1382         1956 my $type = ref $element;
384 1382 50       2517 return undef unless $type;
385 1382 100       4140 return 0 unless ($type =~ /^XML::Mini::Element/);
386 1295         3126 return 1;
387             }
388              
389             sub isNode
390             {
391 735     735 0 826 my $self = shift;
392 735   33     10311 my $element = shift || $self;
393 735         1129 my $type = ref $element;
394 735 50       1257 return undef unless $type;
395 735 100       2262 return 0 unless ($type =~ /^XML::Mini::Node/);
396 684         1901 return 1;
397             }
398              
399              
400             sub insertChild {
401 0     0 1 0 my $self = shift;
402 0         0 my $child = shift;
403 0   0     0 my $idx = shift || 0;
404            
405            
406            
407 0         0 $self->_validateChild($child);
408            
409              
410 0 0 0     0 if ($self->{'_avoidLoops'} || $XML::Mini::AutoSetParent)
411             {
412 0 0       0 if ($self->{'_parent'} == $child)
413             {
414 0         0 my $childName = $child->name();
415 0         0 return XML::Mini->Error("Element::insertChild() Tryng to append parent $childName as child of "
416             . $self->name());
417             }
418 0         0 $child->parent($self);
419             }
420            
421 0         0 my $nextIdx = $self->{'_numChildren'};
422 0         0 my $lastIdx = $nextIdx - 1;
423            
424 0 0       0 if ($idx > $lastIdx)
    0          
425             {
426            
427 0 0       0 if ($idx > $nextIdx)
428             {
429 0         0 $idx = $lastIdx + 1;
430             }
431 0         0 $self->{'_children'}->[$idx] = $child;
432 0         0 $self->{'_numChildren'}++;
433 0 0       0 $self->{'_numElementChildren'}++ if ($self->isElement($child));
434            
435             } elsif ($idx >= 0)
436             {
437 0         0 my @removed = splice(@{$self->{'_children'}}, $idx);
  0         0  
438 0         0 push @{$self->{'_children'}}, ($child, @removed);
  0         0  
439            
440 0         0 $self->{'_numChildren'}++;
441 0 0       0 $self->{'_numElementChildren'}++ if ($self->isElement($child));
442             } else {
443 0         0 my $revIdx = (-1 * $idx) % $self->{'_numChildren'};
444 0         0 my $newIdx = $self->{'_numChildren'} - $revIdx;
445            
446 0 0       0 if ($newIdx < 0)
447             {
448 0         0 return XML::Mini->Error("Element::insertChild() Ended up with a negative index? ($newIdx)");
449             }
450            
451 0         0 return $self->insertChild($child, $newIdx);
452             }
453            
454 0         0 return $child;
455             }
456            
457              
458             sub appendChild
459             {
460 1119     1119 1 1320 my $self = shift;
461 1119         1140 my $child = shift;
462            
463 1119         2132 $self->_validateChild($child);
464            
465 1119 50 33     3653 if ($self->{'_avoidLoops'} || $XML::Mini::AutoSetParent)
466             {
467 0 0       0 if ($self->{'_parent'} == $child)
468             {
469 0         0 my $childName = $child->name();
470 0         0 return XML::Mini->Error("Element::appendChild() Tryng to append parent $childName as child of "
471             . $self->name());
472             }
473 0         0 $child->parent($self);
474             }
475            
476 1119         1489 $self->{'_numElementChildren'}++; #Note that we're addind a Element child
477            
478 1119         1600 my $idx = $self->{'_numChildren'}++;
479 1119         1920 $self->{'_children'}->[$idx] = $child;
480            
481 1119         2372 return $self->{'_children'}->[$idx];
482             }
483              
484             sub prependChild
485             {
486 1     1 1 164 my $self = shift;
487 1         2 my $child = shift;
488            
489 1         3 $self->_validateChild($child);
490            
491 1 50 33     23 if ($self->{'_avoidLoops'} || $XML::Mini::AutoSetParent)
492             {
493 0 0       0 if ($self->{'_parent'} == $child)
494             {
495 0         0 my $childName = $child->name();
496 0         0 return XML::Mini->Error("Element::appendChild() Tryng to append parent $childName as child of "
497             . $self->name());
498             }
499 0         0 $child->parent($self);
500             }
501            
502 1         1 $self->{'_numElementChildren'}++; #Note that we're addind a Element child
503            
504 1         3 my $idx = $self->{'_numChildren'}++;
505 1         1 unshift(@{$self->{'_children'}}, $child);
  1         3  
506            
507 1         3 return $self->{'_children'}->[0];
508             }
509            
510              
511             sub createChild
512             {
513 1097     1097 1 17652 my $self = shift;
514 1097         1595 my $name = shift;
515 1097         1253 my $value = shift; # optionally fill child with
516            
517 1097 50       2397 unless (defined $name)
518             {
519 0         0 return XML::Mini->Error("Element::createChild() Must pass a NAME to createChild.");
520             }
521            
522 1097         2875 my $child = XML::Mini::Element->new($name);
523            
524 1097         2369 $child = $self->appendChild($child);
525            
526 1097 100       2214 if (defined $value)
527             {
528 19 50       75 if ($value =~ m/^\s*[Ee\d\.\+-]+\s*$/)
529             {
530 0         0 $child->numeric($value);
531             } else {
532 19         46 $child->text($value);
533             }
534             }
535            
536 1097         2677 $child->avoidLoops($self->{'_avoidLoops'});
537            
538 1097         2624 return $child;
539             }
540              
541              
542             sub _validateChild {
543 1120     1120   1164 my $self = shift;
544 1120         1156 my $child = shift;
545            
546            
547 1120 50       2125 return XML::Mini->Error("Element:_validateChild() need to pass a non-NULL Element child")
548             unless (defined $child);
549            
550 1120 50       2525 return XML::Mini->Error("Element::_validateChild() must pass an Element object to appendChild.")
551             unless ($self->isElement($child));
552            
553            
554 1120         2203 my $childName = $child->name();
555            
556 1120 50       2399 return XML::Mini->Error("Element::_validateChild() children must be named")
557             unless (defined $childName);
558            
559 1120 50 33     4776 if ($child == $self)
    50          
560             {
561 0         0 return XML::Mini->Error("Element::_validateChild() Trying to append self as own child!");
562             } elsif ( $self->{'_avoidLoops'} && $child->parent())
563             {
564            
565 0         0 return XML::Mini->Error("Element::_validateChild() Trying to append a child ($childName) that already has a parent set "
566             . "while avoidLoops is on - aborting");
567             }
568            
569 1120         1647 return 1;
570             }
571              
572              
573             sub removeChild {
574 3     3 1 223 my $self = shift;
575 3         7 my $child = shift;
576            
577 3 50       10 unless (defined $child)
578             {
579 0         0 XML::Mini->Log("Element::removeChild() called without an ELEMENT parameter.");
580 0         0 return undef;
581             }
582            
583 3 50       11 unless ($self->{'_numChildren'})
584             {
585 0         0 return XML::Mini->Error("Element::removeChild() called for element without any children.");
586             }
587            
588 3         6 my $childType = ref $child;
589 3 100 66     23 unless ($childType && $childType =~ /XML::Mini::/)
590             {
591             # name of the child...
592             # try to find it...
593 1         5 my $el = $self->getElement($child);
594            
595 1 50       4 return XML::Mini->Error("Element::removeChild() called with element _name_ $child, but could not find any such element")
596             unless ($el);
597            
598 1         2 $child = $el;
599             }
600            
601 3         15 my $foundChild;
602 3         13 my $idx = 0;
603 3   66     28 while ($idx < $self->{'_numChildren'} && ! $foundChild)
604             {
605 5 100       16 if ($self->{'_children'}->[$idx] == $child)
606             {
607 3         19 $foundChild = $self->{'_children'}->[$idx];
608             } else {
609 2         12 $idx++;
610             }
611             }
612            
613 3 50       10 unless ($foundChild)
614             {
615 0 0       0 XML::Mini->Log("Element::removeChild() No matching child found.") if ($XML::Mini::Debug);
616 0         0 return undef;
617             }
618            
619 3         5 splice @{$self->{'_children'}}, $idx, 1;
  3         6  
620 3         7 $self->{'_numChildren'}--;
621 3 50       11 if ($foundChild->isElement())
622             {
623 3         6 $self->{'_numElementChildren'}--;
624             }
625            
626 3         7 delete $foundChild->{'_parent'} ;
627 3         26 return $foundChild;
628             }
629              
630             sub removeAllChildren {
631 1     1 1 151 my $self = shift;
632            
633 1 50       4 return undef unless ($self->{'_numChildren'});
634            
635 1         2 my $retList = $self->{'_children'};
636 1         2 delete $self->{'_children'};
637 1         1 $self->{'_numElementChildren'} = 0;
638 1         2 $self->{'_numChildren'} = 0;
639            
640 1         1 foreach my $child (@{$retList})
  1         2  
641             {
642 3         6 delete $child->{'_parent'};
643             }
644            
645 1         2 delete $self->{'_children'};
646 1         3 $self->{'children'} = [];
647            
648 1         3 return $retList;
649             }
650              
651             sub remove {
652 0     0 1 0 my $self = shift;
653            
654 0         0 my $parent = $self->parent();
655            
656 0 0       0 unless ($parent)
657             {
658 0         0 XML::Mini->Log("XML::Mini::Element::remove() called for element with no parent set. Aborting.");
659 0         0 return undef;
660             }
661            
662 0         0 my $removed = $parent->removeChild($self);
663            
664 0         0 return $removed;
665             }
666            
667             sub parent {
668 0     0 1 0 my $self = shift;
669 0         0 my $parent = shift; # optionally set
670            
671 0 0       0 if (defined $parent)
672             {
673 0 0       0 return XML::Mini->Error("Element::parent(): Must pass an instance of Element to set.")
674             unless ($self->isElement($parent));
675 0         0 $self->{'_parent'} = $parent;
676             }
677 0         0 return $self->{'_parent'};
678             }
679            
680             sub avoidLoops
681             {
682 1097     1097 1 1263 my $self = shift;
683 1097         1175 my $setTo = shift; # optionally set
684 1097 50       2276 if (defined $setTo)
685             {
686 1097         1722 $self->{'_avoidLoops'} = $setTo;
687             }
688 1097         1595 return $self->{'_avoidLoops'};
689             }
690              
691              
692             sub toStructure {
693 128     128 0 131 my $self = shift;
694            
695            
696 128         168 my $retHash = {};
697 128         164 my $contents = "";
698 128         140 my $numAdded = 0;
699 128 50       303 if ($self->{'_attributes'})
700             {
701 128         146 while (my ($attname, $attvalue) = each %{$self->{'_attributes'}})
  163         560  
702             {
703 35         72 $retHash->{$attname} = $attvalue;
704 35         60 $numAdded++;
705             }
706             }
707            
708 128   100     313 my $numChildren = $self->{'_numChildren'} || 0;
709 128         268 for (my $i=0; $i < $numChildren ; $i++)
710             {
711 213         314 my $thisChild = $self->{'_children'}->[$i];
712 213 100       428 if ($self->isElement($thisChild))
713             {
714 126         229 my $name = $thisChild->name();
715 126         267 my $struct = $thisChild->toStructure();
716 126         183 my $existing = $retHash->{$name};
717            
718 126 100       229 if ($existing)
719             {
720 27   50     60 my $existingType = ref $existing || "";
721 27 100       47 if ($existingType eq 'ARRAY')
722             {
723 22         21 push @{$existing}, $struct;
  22         47  
724             } else {
725 5         11 my $arrayRef = [$existing, $struct];
726 5         9 $retHash->{$name} = $arrayRef;
727             }
728             } else {
729            
730 99         192 $retHash->{$name} = $struct;
731             }
732            
733            
734 126         312 $numAdded++;
735            
736             } else {
737 87         217 $contents .= $thisChild->getValue();
738             }
739             }
740            
741 128 100       190 if ($numAdded)
742             {
743 41 100       70 if (length($contents))
744             {
745 2         7 $retHash->{'-content'} = $contents;
746             }
747            
748 41         71 return $retHash;
749             } else {
750 87         188 return $contents;
751             }
752              
753             }
754              
755              
756             sub toString
757             {
758 144     144 1 177 my $self = shift;
759 144   100     343 my $depth = shift || 0;
760              
761 144 50       310 if ($depth == $XML::Mini::NoWhiteSpaces)
762             {
763 0         0 return $self->toStringNoWhiteSpaces();
764             }
765            
766 144         153 my $retString;
767 144         152 my $attribString = '';
768 144         257 my $elementName = $self->{'_name'};
769 144         396 my $spaces = $self->_spaceStr($depth);
770            
771 144         184 foreach my $atName (sort keys %{$self->{'_attributes'}})
  144         718  
772             {
773 33         124 $attribString .= qq|$atName="$self->{'_attributes'}->{$atName}" |;
774             }
775            
776 144         259 $retString = "$spaces<$elementName";
777            
778 144 100       260 if ($attribString)
779             {
780 33         172 $attribString =~ s/\s*$//;
781 33         52 $retString .= " $attribString";
782             }
783            
784 144 100       289 if (! $self->{'_numChildren'})
785             {
786 7         11 $retString .= " />\n";
787 7         24 return $retString;
788             }
789            
790             # Else, we do have kids - sub element or nodes
791            
792 137         141 my $allChildrenAreNodes = 1;
793            
794 137         169 my $i=0;
795 137   100     637 while ($allChildrenAreNodes && $i < $self->{'_numChildren'})
796             {
797 138 100       328 $allChildrenAreNodes = 0 unless ($self->isNode($self->{'_children'}->[$i]));
798 138         490 $i++;
799             }
800            
801            
802 137         158 $retString .= ">";
803 137 100       243 $retString .= "\n" unless ($allChildrenAreNodes);
804            
805            
806 137         157 my $nextDepth = $depth + 1;
807            
808 137         303 for($i=0; $i < $self->{'_numChildren'}; $i++)
809             {
810 233         753 my $newStr = $self->{'_children'}->[$i]->toString($nextDepth);
811 233 50       515 if (defined $newStr)
812             {
813 233 100 100     1342 if ( ! ($allChildrenAreNodes || $newStr =~ m|\n$|) )
814             {
815 1         2 $newStr .= "\n";
816             }
817            
818 233         999 $retString .= $newStr;
819             } # end if newStr returned
820             } # end loop over all children
821            
822 137 100       252 $retString .= "$spaces" unless ($allChildrenAreNodes);
823            
824 137         195 $retString .= "\n";
825 137         350 return $retString;
826             }
827              
828             sub toStringNoWhiteSpaces
829             {
830 0     0 0 0 my $self = shift;
831            
832 0         0 my $retString;
833 0         0 my $attribString = '';
834 0         0 my $elementName = $self->{'_name'};
835            
836 0         0 while (my ($atName, $atVal) = each %{$self->{'_attributes'}})
  0         0  
837             {
838 0         0 $attribString .= qq|$atName="$atVal" |;
839             }
840            
841 0         0 $retString = "<$elementName";
842            
843 0 0       0 if ($attribString)
844             {
845 0         0 $attribString =~ s/\s*$//;
846 0         0 $retString .= " $attribString";
847             }
848            
849 0 0       0 if (! $self->{'_numChildren'})
850             {
851 0         0 $retString .= '/>';
852 0         0 return $retString;
853             }
854            
855             # Else, we do have kids - sub element or nodes
856            
857 0         0 $retString .= '>';
858            
859 0         0 for(my $i=0; $i < $self->{'_numChildren'}; $i++)
860             {
861 0         0 my $newStr = $self->{'_children'}->[$i]->toStringNoWhiteSpaces();
862 0 0       0 $retString .= $newStr if (defined $newStr);
863             } # end loop over all children
864              
865 0         0 $retString .= "";
866 0         0 return $retString;
867             }
868              
869             sub createNode
870             {
871 597     597 1 785 my $self = shift;
872 597         786 my $value = shift;
873            
874 597         1860 my $newNode = XML::Mini::Node->new($value);
875 597 50       1257 return undef unless ($newNode);
876            
877 597         1238 my $appendedNode = $self->appendNode($newNode);
878 597         1432 return $appendedNode;
879             }
880              
881             sub appendNode
882             {
883 597     597 1 879 my $self = shift;
884 597         632 my $node = shift;
885            
886 597 50       1096 return XML::Mini->Error("Element::appendNode() need to pass a non-NULL XML::MiniNode.")
887             unless (defined $node);
888            
889 597 50       1165 return XML::Mini->Error("Element::appendNode() must pass a XML::MiniNode object to appendNode.")
890             unless ($self->isNode($node));
891            
892            
893            
894 597 50       1492 if ($XML::Mini::AutoSetParent)
895             {
896 0         0 $node->parent($self);
897             }
898            
899 597 50       1010 if ($XML::Mini::Debug)
900             {
901 0         0 XML::Mini->Log("Appending node to " . $self->{'_name'});
902             }
903            
904 597         1191 my $idx = $self->{'_numChildren'}++;
905 597         1164 $self->{'_children'}->[$idx] = $node;
906            
907 597         1207 return $self->{'_children'}->[$idx];
908             }
909              
910             1;
911              
912             __END__