=item xml_child As a shortcut - given an XML element, find the child with the given name, or, if there isn't one, create it. This is the swiss-army-knife of XML functions for this project. If you do not understand this function after reading all the code, try again or ask questions - this function is called for 90% of the work done to this XML file. Input: named parameters: =over 4 =item parent The parent object to look in. =item child The child name to look for/create =item action If the child needs to be created, this is the action to paste, see L. Default is 'last_child'. =item relto If the child needs to be created, this is where the action is relative to. =item def_text If the child needs to be created, this is its default text, default to blank. =item def_attr If the child needs to be created, this is its default attributes =item override_attr Whether or not the child existed prior, override its attributes with these =item override_text Whether or not the child existed prior, override its text with this. =back There is no option for sub elements as that would just get way too confusing. Output: XML::Twig::Elt =cut sub xml_child { my %opts = @_; croak "parent option to xml_child must be XML::Twig::Elt" unless $opts{parent} and ref $opts{parent} and $opts{parent}->isa('XML::Twig::Elt'); my $child_name = $opts{child}; #$child_name = "$child_name" unless $child_name =~ m.^/.; my @children = $opts{parent}->children($child_name); croak "$child_name matches too many descendants" unless scalar @children < 2; # If no such child, create it. my $child; if (@children) { $child = $children[0]; } else { # here we need to create and paste a new element. my $action = $opts{action} || 'last_child'; my $rel = $opts{relto} || $opts{parent}; $child_name =~ s#(?:.*/)?(\w+).*#$1#; my @params = $child_name; push @params, $opts{def_attr} if exists $opts{def_attr}; push @params, $opts{def_text} if exists $opts{def_text}; $child = XML::Twig::Elt->new(@params); #eval { $child->paste($action, $rel); #}; if ($@) #{ # print STDERR "pasting $action ", $rel->gi(), " (name = ", $rel->att('name'), ") failed\n"; # die $@; #} } $child->set_text($opts{override_text}) if exists $opts{override_text}; $child->set_att(%{$opts{override_attr}}) if exists $opts{override_attr}; $child; } #### $child = xml_child(parent => $elt, child => 'built', action => 'after', relto => $prev_child, def_text => '19700101 000000.000-0000'); $prev_child = $child; $child = xml_child(parent => $elt, child => 'shareable', action => 'after', relto => $prev_child, override_text => 'true');