Data::Edit::Xml - Edit data held in the XML format.
Create a new XML parse tree:
my $a = Data::Edit::Xml::new("<a><b><c/></b><d><c/></d></a>");
Print the parse tree:
say STDERR -p $a;
to get:
<a> <b> <c/> </b> <d> <c/> </d> </a>
Cut out c under b but not under d in the created tree by traversing in post-order applying a sub to each node to cut out c when we are at c under b under a.
In object oriented style:
$a -> by(sub {$_ -> cut(qw(c b a))});
In operator style:
$a x= sub{--$_ if $_ <= [qw(c b a)]};
Print the transformed parse tree
<a> <b/> <d> <c/> </d> </a>
To transform a series of bullets into <ul><li>...</li></ul>, parse the input XML:
my $a = Data::Edit::Xml::new(<<END); <a> <p>• Minimum 1 number</p> <p>• No leading, trailing, or embedded spaces</p> <p>• Not case-sensitive</p> </a> END
Traverse the resulting parse tree, removing bullets and changing <p> to <li>, <a> to <ul>:
$a->change(q(ul))->by(sub # Change to <ul> and then traverse parse tree {$_->up->change(q(li)) if $_->text(q(p)) and $_->text =~ s/\A•\s*//s # Remove leading bullets from text and change <p> to <li> });
Print to get:
ok -p $a eq <<END; # Results <ul> <li>Minimum 1 number</li> <li>No leading, trailing, or embedded spaces</li> <li>Not case-sensitive</li> </ul> END
To transform some DocBook XML into Dita:
use Data::Edit::Xml; # Parse the DocBook XML my $a = Data::Edit::Xml::new(<<END); <sli> <li> <p>Diagnose the problem</p> <p>This can be quite difficult</p> <p>Sometimes impossible</p> </li> <li> <p><pre>ls -la</pre></p> <p><pre> sub listToSteps($$;$) # Change B<ol/ul> to B<steps>. {my ($project, $o, $s) = @_; # Project, List node in parse tree, "step" or "substep" return unless $o->at(qw(ol)) or $o->at(qw(ul)); $s //= q(step); # Default is to steps for my $l($o->contents) {$l->change(qw(cmd))->wrapWith($s); for my $L($l->contents) {$L->unwrap if $L->at(qw(p cmd)); } } $o->change($s.q(s)); $o } # listToSteps
sub stepsToList($$) # Change steps to ol. {my ($project, $o) = @_; # Project, Steps node in parse tree return undef unless $o->at(qw(steps)); for my $l($o->contents) {$l->change(qw(li)); for my $L($l->contents) {$L->unwrap if $L->at(qw(cmd)); } } $o->change(q(ol)); $o } # stepsToList
sub contextFreeConversionsFromDocBookToDita($) # Make obvious changes to the parse tree of a DocBook file to make it look more like Dita. {my ($project) = @_; # Project
$project->parse->by(sub # Do the obvious conversions {my ($o) = @_; my %change = # Tags that should be changed (book=>q(bookmap), code=>q(codeph), emphasis=>q(b), figure=>q(fig), # PS-35 guibutton=>q(uicontrol), # PS-32 guilabel=>q(uicontrol), guimenu=>q(uicontrol), # PS-33 itemizedlist=>q(ol), listitem=>q(li), menuchoice=>q(uicontrol), orderedlist=>q(ol), para=>q(p), replaceable=>q(varname), # PS-42 variablelist=>q(dl), # PS-37 varlistentry=>q(dlentry), # PS-37 command=>q(codeph), # Needs approval from Micalea ); my %deleteAttributesDependingOnValue = # Attributes that should be deleted if they have specified values (b=>[[qw(role bold)], [qw(role underline)]], ); my @deleteAttributesUnconditionally = # Attributes that should be deleted unconditionally from all tags that have them qw(version xml:id xmlns xmlns:xi xmlns:xl xmlns:d); my %renameAttributes = # Attributes that should be renamed (xref=>[[qw(linkend href)]], fig =>[[qw(role outputclass)], [qw(xml:id id)]], # PS-35 imagedata =>[[qw(contentwidth width)], [qw(fileref href)]], # PS-38 ); for my $old(sort keys %change) # Perform requested tag changes {$o->change($change{$old}) if $o->at($old); } for my $tag(sort keys %deleteAttributesDependingOnValue) # Delete specified attributes if they have the right values {if ($o->at($tag)) {$o->deleteAttr(@$_) for @{$deleteAttributesDependingOnValue{$tag}}; } } $o->deleteAttrs(@deleteAttributesUnconditionally); # Delete attributes unconditionally from all tags that have them for my $tag(sort keys %renameAttributes) # Rename specified attributes {if ($o->at($tag)) {$o->renameAttr(@$_) for @{$renameAttributes{$tag}}; } } }); } # contextFreeConversionsFromDocBookToDita
drwxr-xr-x 2 phil phil 4096 Jun 15 2016 Desktop drwxr-xr-x 2 phil phil 4096 Nov 9 20:26 Downloads </pre></p> </li> </sli> END
# Transform to Dita step 1 $a->by(sub {my ($o, $p) = @_; if ($o->at(qw(pre p li sli)) and $o->isOnlyChild) {$o->change($p->isFirst ? qw(cmd) : qw(stepresult)); $p->unwrap; } elsif ($o->at(qw(li sli)) and $o->over(qr(\Ap( p)+\Z))) {$_->change($_->isFirst ? qw(cmd) : qw(info)) for $o->contents; } }); # Transform to Dita step 2 $a->by(sub {my ($o) = @_; $o->change(qw(step)) if $o->at(qw(li sli)); $o->change(qw(steps)) if $o->at(qw(sli)); $o->id = 's'.($o->position+1) if $o->at(qw(step)); $o->id = 'i'.($o->index+1) if $o->at(qw(info)); $o->wrapWith(qw(screen)) if $o->at(qw(CDATA stepresult)); }); # Print the results say STDERR -p $a;
Produces:
<steps> <step id="s1"> <cmd>Diagnose the problem </cmd> <info id="i1">This can be quite difficult </info> <info id="i2">Sometimes impossible </info> </step> <step id="s2"> <cmd>ls -la </cmd> <stepresult> <screen> drwxr-xr-x 2 phil phil 4096 Jun 15 2016 Desktop drwxr-xr-x 2 phil phil 4096 Nov 9 20:26 Downloads </screen> </stepresult> </step> </steps>
Edit data held in the XML format.
The following sections describe the methods in each functional area of this module. For an alphabetic listing of all methods by name see Index.
These methods are the ones most likely to be of immediate use to anyone using this module for the first time:
at
Confirm that the node has the specified ancestry and return the starting node if it does else undef. Ancestry is specified by providing the expected tags that the parent, the parent's parent etc. must match at each level. If undef is specified then any tag is assumed to match at that level. If a regular expression is specified then the current parent node tag must match the regular expression at that level. If all supplied tags match successfully then the starting node is returned else undef
attr
Return the value of an attribute of the current node as an lvalue sub.
by
Post-order traversal of a parse tree or sub tree calling the specified sub at each node and returning the specified starting node. The sub is passed references to the current node and all of its ancestors. A reference to the current node is also made available via $_. This is equivalent to the x= operator.
change
Change the name of a node, optionally confirming that the node is in a specified context and return the node.
cut
Cut out a node so that it can be reinserted else where in the parse tree.
go
Return the node reached from the specified node via the specified path: (index position?)* where index is the tag of the next node to be chosen and position is the optional zero based position within the index of those tags under the current node. Position defaults to zero if not specified. Position can also be negative to index back from the top of the index array. * can be used as the last position to retrieve all nodes with the final tag.
new
New parse - call this method statically as in Data::Edit::Xml::new(file or string) or with no parameters and then use "input", "inputFile", "inputString", "errorFile" to provide specific parameters for the parse, then call "parse" to perform the parse and return the parse tree.
prettyString
Return a readable string representing a node of a parse tree and all the nodes below it. Or use -p $node
putLast
Place a cut out or new node last in the content of the specified node and return the new node.
unwrap
Unwrap a node by inserting its content into its parent at the point containing the node and return the parent node.
wrapWith
Wrap the original node in a new node forcing the original node down - deepening the parse tree - return the new wrapping node.
Create a parse tree, either by parsing a file or string, or, node by node, or, from another parse tree
Construct a parse tree from a file or a string
Parameter Description 1 $fileNameOrString File name or string
Example:
my $a = Data::Edit::Xml::new(<<END); <a> <b> <c id="42" match="mm"/> </b> <d> <e/> </d> </a> END ok -p $a eq <<END; <a> <b> <c id="42" match="mm"/> </b> <d> <e/> </d> </a> END
This is a static method and so should be invoked as:
Data::Edit::Xml::new
The name of the tag to be used to represent text - this tag must not also be used as a command tag otherwise the parser will confess.
ok Data::Edit::Xml::cdata eq q(CDATA);
Parse input XML specified via: inputFile, input or inputString.
Parameter Description 1 $parser Parser created by L</new>
my $x = Data::Edit::Xml::new; $x->inputString = <<END; <a id="aa"><b id="bb"><c id="cc"/></b></a> END $x->parse; ok -p $x eq <<END; <a id="aa"> <b id="bb"> <c id="cc"/> </b> </a> END
Construct a parse tree node by node.
Create a new text node.
Parameter Description 1 undef Any reference to this package 2 $text Content of new text node
ok -p $x eq <<END; <a class="aa" id="1"> <b class="bb" id="2"/> </a> END $x->putLast($x->newText("t")); ok -p $x eq <<END; <a class="aa" id="1"> <b class="bb" id="2"/> t </a> END
Create a new non text node.
Parameter Description 1 undef Any reference to this package 2 $command The tag for the node 3 %attributes Attributes as a hash.
my $x = Data::Edit::Xml::newTree("a", id=>1, class=>"aa"); $x->putLast($x->newTag("b", id=>2, class=>"bb")); ok -p $x eq <<END; <a class="aa" id="1"> <b class="bb" id="2"/> </a> END
Create a new tree.
Parameter Description 1 $command The name of the root node in the tree 2 %attributes Attributes of the root node in the tree as a hash.
my $x = Data::Edit::Xml::newTree("a", id=>1, class=>"aa"); ok -s $x eq '<a class="aa" id="1"/>';
Replace < > " with < > " Larry Wall's excellent Xml parser unfortunately replaces < > " & etc. with their expansions in text by default and does not seem to provide an obvious way to stop this behavior, so we have to put them back gain using this method. Worse, we cannot decide whether to replace & with & or leave it as is: consequently you might have to examine the instances of & in your output text and guess based on the context.
Parameter Description 1 $string String to be edited.
ok Data::Edit::Xml::replaceSpecialChars(q(<">)) eq "<">";
Attributes of a node in a parse tree. For instance the attributes associated with an XML tag are held in the attributes attribute. It should not be necessary to use these attributes directly unless you are writing an extension to this module. Otherwise you should probably use the methods documented in other sections to manipulate the parse tree as they offer a safer interface at a higher level.
Content of command: the nodes immediately below this node in the order in which they appeared in the source text, see also "Contents".
Nodes by number.
A hash added to the node for use by the programmer during transformations. The data in this hash will not be printed by any of the printed methods and so can be used to add data to the parse tree that will not be seen in any output xml produced from the parse tree.
The attributes of this node, see also: "Attributes". The frequently used attributes: class, id, href, outputclass can be accessed by an lvalue method as in: $node->id = 'c1'.
Conditional strings attached to a node, see "Conditions".
Indexes to sub commands by tag in the order in which they appeared in the source text.
The labels attached to a node to provide addressability from other nodes, see: "Labels".
Error listing file. Use this parameter to explicitly set the name of the file that will be used to write an parse errors to. By default this file is named: zzzParseErrors/out.data.
Source file of the parse if this is the parser root node. Use this parameter to explicitly set the file to be parsed.
Source of the parse if this is the parser root node. Use this parameter to specify some input either as a string or as a file name for the parser to convert into a parse tree.
Source string of the parse if this is the parser root node. Use this parameter to explicitly set the string to be parsed.
Last number used to number a node in this parse tree.
Number of this node, see findByNumber.
Parent node of this node or undef if the parser root node. See also "Traversal" and "Navigation". Consider as read only.
Parser details: the root node of a tree is the parse node for that tree. Consider as read only.
Tag name for this node, see also "Traversal" and "Navigation". Consider as read only.
Text of this node but only if it is a text node, i.e. the tag is cdata() <=> "isText" is true.
Construct a parse tree from another parse tree
Returns a renewed copy of the parse tree, optionally checking that the starting node is in a specified context: use this method if you have added nodes via the "Put as text" methods and wish to traverse their parse tree.
Returns the starting node of the new parse tree or undef if the optional context constraint was supplied but not satisfied.
Parameter Description 1 $node Node to renew from 2 @context Optional context
Use the @context parameter to provide an optional context for this method as understood by method at . If a context is supplied and the node specified by the first parameter is not in this context then this method returns undef immediately.
my $a = Data::Edit::Xml::new("<a/>"); $a->putFirstAsText(qq(<b/>)); ok !$a->go(q(b)); my $A = $a->renew; ok -t $A->go(q(b)) eq q(b)
Return a clone of the parse tree optionally checking that the starting node is in a specified context: the parse tree is cloned without converting it to string and reparsing it so this method will not renew any nodes added as text.
Parameter Description 1 $node Node to clone from 2 @context Optional context
my $a = Data::Edit::Xml::new("<a> </a>"); my $A = $a->clone; ok -s $A eq q(<a/>); ok $a->equals($A); my $x = Data::Edit::Xml::new(<<END); <x> <a>aaa <b>bbb</b> ccc <d>ddd</d> eee </a> </x> END my $y = $x->clone; ok !$x->diff($y);
Return the first node if the two parse trees have identical representations via string, else undef.
Parameter Description 1 $node1 Parse tree 1 2 $node2 Parse tree 2.
my $a = Data::Edit::Xml::new("<a> </a>"); my $A = $a->clone; ok -s $A eq q(<a/>); ok $a->equals($A);
Use equalsX to execute equals but die 'equals' instead of returning undef
Return () if the dense string representations of the two nodes are equal, else up to the first N (default 16) characters of the common prefix before the point of divergence and the remainder of the string representation of each node from the point of divergence. All <!-- ... --> comments are ignored during this comparison and all spans of whitespace are reduced to a single blank.
Parameter Description 1 $first First node 2 $second Second node 3 $N Maximum length of difference strings to return
my $x = Data::Edit::Xml::new(<<END); <x> <a>aaa <b>bbb</b> ccc <d>ddd</d> eee </a> </x> END ok !$x->diff($x); my $y = $x->clone; ok !$x->diff($y); $y->first->putLast($x->newTag(q(f))); ok nws(<<END) eq nws(-p $y); <x> <a>aaa <b>bbb</b> ccc <d>ddd</d> eee <f/> </a> </x> END is_deeply [$x->diff($y)], ["<d>ddd</d> eee <", "/a></x>", "f/></a></x>"]; is_deeply [diff(-p $x, $y)], ["<d>ddd</d> eee <", "/a></x>", "f/></a></x>"]; is_deeply [$x->diff(-p $y)], ["<d>ddd</d> eee <", "/a></x>", "f/></a></x>"]; my $X = writeFile(undef, -p $x); my $Y = writeFile(undef, -p $y); is_deeply [diff($X, $Y)], ["<d>ddd</d> eee <", "/a></x>", "f/></a></x>"];
Save a copy of the parse tree to a file which can be restored and return the saved node.
Parameter Description 1 $node Parse tree 2 $file File.
$y->save($f); my $Y = Data::Edit::Xml::restore($f); ok $Y->equals($y);
Return a parse tree from a copy saved in a file by "save".
Parameter Description 1 $file File
Use restoreX to execute restore but die 'restore' instead of returning undef
Data::Edit::Xml::restore
Expand the includes mentioned in a parse tree: any tag that ends in include is assumed to be an include directive. The file to be included is named on the href keyword. If the file to be included is a relative file name, i.e. it does not begin with / then this file is made absolute relative to the file from which this parse tree was obtained.
Parameter Description 1 $x Parse tree
my @files = (writeFile("in1/a.xml", q(<a id="a"><include href="../in2/b.xml"/></a>)), writeFile("in2/b.xml", q(<b id="b"><include href="c.xml"/></b>)), writeFile("in2/c.xml", q(<c id="c"/>))); my $x = Data::Edit::Xml::new(fpf(currentDirectory, $files[0])); $x->expandIncludes; ok <<END eq -p $x; <a id="a"> <b id="b"> <c id="c"/> </b> </a> END
Create a string representation of the parse tree with optional selection of nodes via conditions.
Normally use the methods in Pretty to format the XML in a readable yet reparseable manner; use Dense string to format the XML densely in a reparseable manner; use the other methods to produce unreparseable strings conveniently formatted to assist various specialized operations such as debugging CDATA, using labels or creating tests. A number of the file test operators can also be conveniently used to print parse trees in these formats.
Pretty print the parse tree.
Parameter Description 1 $node Start node 2 $depth Optional depth.
my $s = <<END; <a> <b> <A/> <B/> </b> <c> <C/> <D/> </c> </a> END my $a = Data::Edit::Xml::new($s); ok $s eq $a->prettyString; ok $s eq -p $a;
Return a readable string representing a node of a parse tree and all the nodes below it with a number attached to each tag. The node numbers can then be used as described in Order to monitor changes to the parse tree.
my $s = <<END; <a> <b> <A/> <B/> </b> <c> <C/> <D/> </c> </a> END $a->numberTree; ok $a->prettyStringNumbered eq <<END; <a id="1"> <b id="2"> <A id="3"/> <B id="4"/> </b> <c id="5"> <C id="6"/> <D id="7"/> </c> </a> END
Return a readable string representing a node of a parse tree and all the nodes below it with the text fields wrapped with <CDATA>...</CDATA>.
my $a = Data::Edit::Xml::new("<a><b>A</b></a>"); my $b = $a->first; $b->first->replaceWithBlank; ok $a->prettyStringCDATA eq <<END; <a> <b><CDATA> </CDATA></b> </a> END
Return a readable string representing all the nodes below a node of a parse tree.
Parameter Description 1 $node Start node.
my $s = <<END; <a> <b> <A/> <B/> </b> <c> <C/> <D/> </c> </a> END ok $a->prettyStringContent eq <<END; <b> <A/> <B/> </b> <c> <C/> <D/> </c> END
Return a readable string representing all the nodes below a node of a parse tree with numbering added.
my $s = <<END; <a> <b> <c/> </b> </a> END my $a = Data::Edit::Xml::new($s); $a->numberTree; ok $a->prettyStringContentNumbered eq <<END; <b id="2"> <c id="3"/> </b> END ok $a->go(qw(b))->prettyStringContentNumbered eq <<END; <c id="3"/> END
Add the standard xml header to a string
Parameter Description 1 $string String to which a standard xml header should be prefixed
ok xmlHeader("<a/>") eq <<END; <?xml version="1.0" encoding="UTF-8"?> <a/> END
Data::Edit::Xml::xmlHeader
Print the parse tree.
Return a dense string representing a node of a parse tree and all the nodes below it. Or use -s $node
ok -p $a eq <<END; <a> <b> <c id="42" match="mm"/> </b> <d> <e/> </d> </a> END ok -s $a eq '<a><b><c id="42" match="mm"/></b><d><e/></d></a>';
Return a quoted string representing a parse tree a node of a parse tree and all the nodes below it. Or use -o $node
Parameter Description 1 $node Start node
my $s = <<END; <a> <b> <A/> <B/> </b> <c> <C/> <D/> </c> </a> END ok $a->stringQuoted eq q('<a><b><A/><B/></b><c><C/><D/></c></a>');
Return a string representing the specified parse tree with the id attribute of each node set to the Labels attached to each node.
ok $x->stringReplacingIdsWithLabels eq '<a><b><c/></b></a>'; $b->addLabels(1..4); $c->addLabels(5..8); ok $x->stringReplacingIdsWithLabels eq '<a><b id="1, 2, 3, 4"><c id="5, 6, 7, 8"/></b></a>'; my $s = $x->stringReplacingIdsWithLabels; ok $s eq '<a><b id="1, 2, 3, 4"><c id="5, 6, 7, 8"/></b></a>';
Return a string representing all the nodes below a node of a parse tree.
my $s = <<END; <a> <b> <A/> <B/> </b> <c> <C/> <D/> </c> </a> END ok $a->stringContent eq "<b><A/><B/></b><c><C/><D/></c>";
Return a string representing a node showing the attributes, labels and node number
Parameter Description 1 $node Node.
ok $x->stringReplacingIdsWithLabels eq '<a><b><c/></b></a>'; my $b = $x->go(q(b)); $b->addLabels(1..2); $b->addLabels(3..4); ok $x->stringReplacingIdsWithLabels eq '<a><b id="1, 2, 3, 4"><c/></b></a>'; $b->numberTree; ok -S $b eq "b(2) 0:1 1:2 2:3 3:4";
Print a subset of the the parse tree determined by the conditions attached to it.
Return a string representing a node of a parse tree and all the nodes below it subject to conditions to select or reject some nodes.
Parameter Description 1 $node Start node 2 @conditions Conditions to be regarded as in effect.
my $a = Data::Edit::Xml::new(<<END); <a> <b> <c/> <d/> </b> </a> END my $b = $a >= 'b'; my ($c, $d) = $b->contents; $b->addConditions(qw(bb BB)); $c->addConditions(qw(cc CC)); ok $a->stringWithConditions eq '<a><b><c/><d/></b></a>'; ok $a->stringWithConditions(qw(bb)) eq '<a><b><d/></b></a>'; ok $a->stringWithConditions(qw(cc)) eq '<a/>';
Return the node if it has the specified condition and is in the optional context, else return undef
Parameter Description 1 $node Node 2 $condition Condition to check 3 @context Optional context
$b->addConditions(qw(bb BB)); $c->addConditions(qw(cc CC)); ok $c->condition(q(cc)); ok !$c->condition(q(dd)); ok $c->condition(q(cc), qw(c b a));
Use conditionX to execute condition but die 'condition' instead of returning undef
Return the node if it has any of the specified conditions, else return undef
Parameter Description 1 $node Node 2 @conditions Conditions to check
$b->addConditions(qw(bb BB)); $c->addConditions(qw(cc CC)); ok $b->anyCondition(qw(bb cc)); ok !$b->anyCondition(qw(cc CC));
Use anyConditionX to execute anyCondition but die 'anyCondition' instead of returning undef
Return the node if it has all of the specified conditions, else return undef
$b->addConditions(qw(bb BB)); $c->addConditions(qw(cc CC)); ok $b->allConditions(qw(bb BB)); ok !$b->allConditions(qw(bb cc));
Use allConditionsX to execute allConditions but die 'allConditions' instead of returning undef
Add conditions to a node and return the node.
Parameter Description 1 $node Node 2 @conditions Conditions to add.
$b->addConditions(qw(bb BB)); ok join(' ', $b->listConditions) eq 'BB bb';
Delete conditions applied to a node and return the node.
ok join(' ', $b->listConditions) eq 'BB bb'; $b->deleteConditions(qw(BB)); ok join(' ', $b->listConditions) eq 'bb';
Return a list of conditions applied to a node.
Get or set the attributes of nodes in the parse tree. Well Known Attributes can be set directly via lvalue subs. To set or get the values of other attributes use Get or Set Attributes. To delete or rename attributes see: Other Operations on Attributes.
Get or set these attributes of nodes via lvalue subs as in:
$x->href = "#ref";
Attribute audience for a node as an lvalue sub.
Attribute class for a node as an lvalue sub.
Attribute guid for a node as an lvalue sub.
Attribute href for a node as an lvalue sub.
Attribute id for a node as an lvalue sub.
Attribute lang for a node as an lvalue sub.
Attribute navtitle for a node as an lvalue sub.
Attribute otherprops for a node as an lvalue sub.
Attribute outputclass for a node as an lvalue sub.
Attribute props for a node as an lvalue sub.
Attribute style for a node as an lvalue sub.
Attribute type for a node as an lvalue sub.
Get or set the attributes of nodes.
Parameter Description 1 $node Node in parse tree 2 $attribute Attribute name.
my $x = Data::Edit::Xml::new(my $s = <<END); <a number="1"/> END ok $x->attr(qq(number)) == 1; $x->attr(qq(number)) = 2; ok $x->attr(qq(number)) == 2; ok -s $x eq '<a number="2"/>';
Set the values of some attributes in a node and return the node. Identical in effect to setAttrs.
Parameter Description 1 $node Node in parse tree 2 %values (attribute name=>new value)*
ok q(<a a="1" b="1" id="aa"/>) eq -s $a; $a->set(a=>11, b=>undef, c=>3, d=>4, e=>5); }
Set the values of some attributes in a node and return the node. Identical in effect to set.
ok -s $x eq '<a number="2"/>'; $x->setAttr(first=>1, second=>2, last=>undef); ok -s $x eq '<a first="1" number="2" second="2"/>';
Perform operations other than get or set on the attributes of a node
Return the values of the specified attributes of the current node as a list
Parameter Description 1 $node Node in parse tree 2 @attributes Attribute names.
ok -s $x eq '<a first="1" number="2" second="2"/>'; is_deeply [$x->attrs(qw(third second first ))], [undef, 2, 1];
Return the number of attributes in the specified node, optionally ignoring the specified names from the count.
Parameter Description 1 $node Node in parse tree 2 @exclude Optional attribute names to exclude from the count.
ok -s $x eq '<a first="1" number="2" second="2"/>'; ok $x->attrCount == 3; ok $x->attrCount(qw(first second third)) == 1;
Return a sorted list of all the attributes on this node.
Parameter Description 1 $node Node in parse tree.
ok -s $x eq '<a first="1" number="2" second="2"/>'; is_deeply [$x->getAttrs], [qw(first number second)];
Delete the named attribute in the specified node, optionally check its value first, return the node regardless.
Parameter Description 1 $node Node 2 $attr Attribute name 3 $value Optional attribute value to check first.
ok -s $x eq '<a delete="me" number="2"/>'; $x->deleteAttr(qq(delete)); ok -s $x eq '<a number="2"/>';
Delete the specified attributes of the specified node without checking their values and return the node.
Parameter Description 1 $node Node 2 @attrs Names of the attributes to delete
ok -s $x eq '<a first="1" number="2" second="2"/>'; $x->deleteAttrs(qw(first second third number)); ok -s $x eq '<a/>';
Change the name of an attribute in the specified node regardless of whether the new attribute already exists or not and return the node. To prevent inadvertent changes to an existing attribute use changeAttr.
Parameter Description 1 $node Node 2 $old Existing attribute name 3 $new New attribute name.
ok $x->printAttributes eq qq( no="1" word="first"); $x->renameAttr(qw(no number)); ok $x->printAttributes eq qq( number="1" word="first");
Change the name of an attribute in the specified node unless it has already been set and return the node. To make changes regardless of whether the new attribute already exists use renameAttr.
ok $x->printAttributes eq qq( number="1" word="first"); $x->changeAttr(qw(number word)); ok $x->printAttributes eq qq( number="1" word="first");
Change the name and value of an attribute in the specified node regardless of whether the new attribute already exists or not and return the node. To prevent inadvertent changes to existing attributes use changeAttrValue.
Parameter Description 1 $node Node 2 $old Existing attribute name 3 $oldValue Existing attribute value 4 $new New attribute name 5 $newValue New attribute value.
ok $x->printAttributes eq qq( number="1" word="first"); $x->renameAttrValue(qw(number 1 numeral I)); ok $x->printAttributes eq qq( numeral="I" word="first");
Change the name and value of an attribute in the specified node unless it has already been set and return the node. To make changes regardless of whether the new attribute already exists use renameAttrValue.
ok $x->printAttributes eq qq( numeral="I" word="first"); $x->changeAttrValue(qw(word second greek mono)); ok $x->printAttributes eq qq( numeral="I" word="first");
Copy all the attributes of the source node to the target node, or, just the named attributes if the optional list of attributes to copy is supplied, overwriting any existing attributes in the target node and return the source node.
Parameter Description 1 $source Source node 2 $target Target node 3 @attr Optional list of attributes to copy
my $x = Data::Edit::Xml::new(<<END); <x> <a a="1" b="2"/> <b b="3" c="4"/> <c/> </x> END my ($a, $b, $c) = $x->contents; $a->copyAttrs($b, qw(aa bb)); ok <<END eq -p $x; <x> <a a="1" b="2"/> <b b="3" c="4"/> <c/> </x> END $a->copyAttrs($b); ok <<END eq -p $x; <x> <a a="1" b="2"/> <b a="1" b="2" c="4"/> <c/> </x> END
Copy all the attributes of the source node to the target node, or, just the named attributes if the optional list of attributes to copy is supplied, without overwriting any existing attributes in the target node and return the source node.
my $x = Data::Edit::Xml::new(<<END); <x> <a a="1" b="2"/> <b b="3" c="4"/> <c/> </x> END my ($a, $b, $c) = $x->contents; $a->copyNewAttrs($b, qw(aa bb)); ok <<END eq -p $x; <x> <a a="1" b="2"/> <b b="3" c="4"/> <c/> </x> END $a->copyNewAttrs($b); ok <<END eq -p $x; <x> <a a="1" b="2"/> <b a="1" b="3" c="4"/> <c/> </x> END
Move all the attributes of the source node to the target node, or, just the named attributes if the optional list of attributes to move is supplied, overwriting any existing attributes in the target node and return the source node.
Parameter Description 1 $source Source node 2 $target Target node 3 @attr Attributes to move
my $x = Data::Edit::Xml::new(<<END); <x> <a a="1" b="2"/> <b b="3" c="4"/> <c/> </x> END my ($a, $b, $c) = $x->contents; $a->moveAttrs($c, qw(aa bb)); ok <<END eq -p $x; <x> <a a="1" b="2"/> <b a="1" b="2" c="4"/> <c/> </x> END $b->moveAttrs($c); ok <<END eq -p $x; <x> <a a="1" b="2"/> <b/> <c a="1" b="2" c="4"/> </x> END
Move all the attributes of the source node to the target node, or, just the named attributes if the optional list of attributes to copy is supplied, without overwriting any existing attributes in the target node and return the source node.
Parameter Description 1 $source Source node 2 $target Target node 3 @attr Optional list of attributes to move
my $x = Data::Edit::Xml::new(<<END); <x> <a a="1" b="2"/> <b b="3" c="4"/> <c/> </x> END my ($a, $b, $c) = $x->contents; $b->moveNewAttrs($c, qw(aa bb)); ok <<END eq -p $x; <x> <a a="1" b="2"/> <b a="1" b="3" c="4"/> <c/> </x> END $b->moveNewAttrs($c); ok <<END eq -p $x; <x> <a a="1" b="2"/> <b/> <c a="1" b="3" c="4"/> </x> END ok <<END eq -p $x; <x> <c a="1" b="3" c="4"/> <b/> <a a="1" b="2"/> </x> END
Traverse the parse tree in various orders applying a sub to each node.
This order allows you to edit children before their parents.
Parameter Description 1 $node Starting node 2 $sub Sub to call for each sub node 3 @context Accumulated context.
ok -p $a eq <<END; <a> <b> <c id="42" match="mm"/> </b> <d> <e/> </d> </a> END my $s; $a->by(sub{$s .= $_->tag}); ok $s eq "cbeda"
Post-order traversal of a parse tree calling the specified sub at each node as long as this sub does not die. The traversal is halted if the called sub does die on any call with the reason in ?@ The sub is passed references to the current node and all of its ancestors up to the node on which this sub was called. A reference to the current node is also made available via $_.
Returns the start node regardless of the outcome of calling sub.
Parameter Description 1 $node Start node 2 $sub Sub to call
ok -p $a eq <<END; <a> <b> <c id="42" match="mm"/> </b> <d> <e/> </d> </a> END my $s; $a->byX(sub{$s .= $_->tag}); ok $s eq "cbeda"
Return a list of all the nodes at and below a node in preorder or the empty list if the node is not in the optional context.
Parameter Description 1 $node Starting node 2 @context Optional context
my $a = Data::Edit::Xml::new(<<END); <a> <b> <c id="42" match="mm"/> </b> <d> <e/> </d> </a> END ok -c $e eq q(e d a);
Reverse post-order traversal of a parse tree or sub tree calling the specified sub at each node and returning the specified starting node. The sub is passed references to the current node and all of its ancestors. The value of the current node is also made available via $_.
ok -p $a eq <<END; <a> <b> <c id="42" match="mm"/> </b> <d> <e/> </d> </a> END my $s; $a->byReverse(sub{$s .= $_->tag}); ok $s eq "edcba"
Reverse post-order traversal of a parse tree or sub tree calling the specified sub within eval{} at each node and returning the specified starting node. The sub is passed references to the current node and all of its ancestors. The value of the current node is also made available via $_.
Return a list of all the nodes at and below a node in reverse preorder or the empty list if the node is not in the optional context.
my $a = Data::Edit::Xml::new(<<END); <a> <b> <c id="42" match="mm"/> </b> <d> <e/> </d> </a> END my ($E, $D, $C, $B) = $a->byReverseList; ok -A $C eq q(c id="42" match="mm");
This order allows you to edit children after their parents
Pre-order traversal down through a parse tree or sub tree calling the specified sub at each node and returning the specified starting node. The sub is passed references to the current node and all of its ancestors. The value of the current node is also made available via $_.
my $s; $a->down(sub{$s .= $_->tag}); ok $s eq "abcde"
Pre-order traversal of a parse tree calling the specified sub at each node as long as this sub does not die. The traversal is halted if the called sub does die on any call with the reason in ?@ The sub is passed references to the current node and all of its ancestors up to the node on which this sub was called. A reference to the current node is also made available via $_.
Reverse pre-order traversal down through a parse tree or sub tree calling the specified sub at each node and returning the specified starting node. The sub is passed references to the current node and all of its ancestors. The value of the current node is also made available via $_.
ok -p $a eq <<END; <a> <b> <c id="42" match="mm"/> </b> <d> <e/> </d> </a> END my $s; $a->downReverse(sub{$s .= $_->tag}); ok $s eq "adebc"
Reverse pre-order traversal down through a parse tree or sub tree calling the specified sub within eval{} at each node and returning the specified starting node. The sub is passed references to the current node and all of its ancestors. The value of the current node is also made available via $_.
Visit the parent first, then the children, then the parent again.
Traverse parse tree visiting each node twice calling the specified sub at each node and returning the specified starting node. The subs are passed references to the current node and all of its ancestors. The value of the current node is also made available via $_.
Parameter Description 1 $node Starting node 2 $before Sub to call when we meet a node 3 $after Sub to call we leave a node 4 @context Accumulated context.
my $s; my $n = sub{$s .= $_->tag}; $a->through($n, $n); ok $s eq "abccbdeeda"
Traverse parse tree visiting each node twice calling the specified sub within eval{} at each node and returning the specified starting node. The sub is passed references to the current node and all of its ancestors. The value of the current node is also made available via $_.
Ranges of nodes
Return a list consisting of the specified node and its following siblings optionally including only those nodes that match one of the tags in the specified list.
Parameter Description 1 $start Start node 2 @match Optional list of tags to match
ok -z $a eq <<END; <a id="1"> <b id="2"> <c id="3"> <e id="4"/> </c> <d id="5"> <e id="6"/> </d> <c id="7"> <d id="8"> <e id="9"/> </d> </c> <d id="10"> <e id="11"/> </d> <c id="12"> <d id="13"> <e id="14"/> </d> </c> </b> </a> END my ($d, $c, $D) = $a->findByNumbers(5, 7, 10); my @f = $d->from; ok @f == 4; ok $d == $f[0]; my @F = $d->from(qw(c)); ok @F == 2; ok -M $F[1] == 12; ok $D == $t[-1];
Return a list of the sibling nodes preceding the specified node optionally including only those nodes that match one of the tags in the specified list.
Parameter Description 1 $end End node 2 @match Optional list of tags to match
ok -z $a eq <<END; <a id="1"> <b id="2"> <c id="3"> <e id="4"/> </c> <d id="5"> <e id="6"/> </d> <c id="7"> <d id="8"> <e id="9"/> </d> </c> <d id="10"> <e id="11"/> </d> <c id="12"> <d id="13"> <e id="14"/> </d> </c> </b> </a> END my ($d, $c, $D) = $a->findByNumbers(5, 7, 10); my @t = $D->to; ok @t == 4; my @T = $D->to(qw(c)); ok @T == 2; ok -M $T[1] == 7;
Return a list of the nodes between the specified start and end nodes optionally including only those nodes that match one of the tags in the specified list.
Parameter Description 1 $start Start node 2 $end End node 3 @match Optional list of tags to match
ok -z $a eq <<END; <a id="1"> <b id="2"> <c id="3"> <e id="4"/> </c> <d id="5"> <e id="6"/> </d> <c id="7"> <d id="8"> <e id="9"/> </d> </c> <d id="10"> <e id="11"/> </d> <c id="12"> <d id="13"> <e id="14"/> </d> </c> </b> </a> END my ($d, $c, $D) = $a->findByNumbers(5, 7, 10); my @r = $d->fromTo($D); ok @r == 3; my @R = $d->fromTo($D, qw(c)); ok @R == 1; ok -M $R[0] == 7; ok !$D->fromTo($d); ok 1 == $d->fromTo($d);
Confirm that the position navigated to is the expected position.
Parameter Description 1 $start Starting node 2 @context Ancestry.
my $a = Data::Edit::Xml::new(<<END); <a> <b> <c> <d/> </c> <c> <e/> </c> <c> <f/> </c> </b> </a> END ok $a->go(qw(b c -1 f))->at(qw(f c b a)); ok $a->go(qw(b c 1 e))->at(undef, qr(c|d), undef, qq(a)); ok $d->context eq q(d c b a); ok $d->at(qw(d c b), undef); ok !$d->at(qw(d c b), undef, undef); ok !$d->at(qw(d e b));
Use atX to execute at but die 'at' instead of returning undef
Confirm that the node or one of its ancestors has the specified context as recognized by at and return the first node that matches the context or undef if none do.
ok $d->context eq q(d c b a); ok $d->atOrBelow(qw(d c b a)); ok $d->atOrBelow(qw( c b a)); ok $d->atOrBelow(qw( b a)); ok !$d->atOrBelow(qw( c a));
Use atOrBelowX to execute atOrBelow but die 'atOrBelow' instead of returning undef
Return a list containing: (the specified node, its parent, its parent's parent etc..)
Parameter Description 1 $start Starting node.
$a->numberTree; ok $a->prettyStringNumbered eq <<END; <a id="1"> <b id="2"> <A id="3"/> <B id="4"/> </b> <c id="5"> <C id="6"/> <D id="7"/> </c> </a> END is_deeply [map {-t $_} $a->findByNumber(7)->ancestry], [qw(D c a)];
Return a string containing the tag of the starting node and the tags of all its ancestors separated by single spaces.
ok -p $a eq <<END; <a> <b> <c id="42" match="mm"/> </b> <d> <e/> </d> </a> END ok $a->go(qw(d e))->context eq 'e d a';
Return the singleton text element below this node else return undef
my $a = Data::Edit::Xml::new("<a><b>bb</b><c>cc<d/>ee</c></a>"); ok $a->go(q(b))->containsSingleText->text eq q(bb); ok !$a->go(q(c))->containsSingleText;
Returns the depth of the specified node, the depth of a root node is zero.
ok -z $a eq <<END; <a id="1"> <b id="2"> <c id="3"> <e id="4"/> </c> <d id="5"> <e id="6"/> </d> <c id="7"> <d id="8"> <e id="9"/> </d> </c> <d id="10"> <e id="11"/> </d> <c id="12"> <d id="13"> <e id="14"/> </d> </c> </b> </a> END ok 0 == $a->depth; ok 4 == $a->findByNumber(14)->depth;
Return the specified node if it is first under its parent and optionally has the specified context, else return undef
Parameter Description 1 $node Node 2 @context Optional context
Use isFirstNonBlank to skip a (rare) initial blank text CDATA. Use isFirstNonBlankX to die rather then receive a returned undef or false result.
ok -p $a eq <<END; <a> <b> <c id="42" match="mm"/> </b> <d> <e/> </d> </a> END ok $a->go(q(b))->isFirst;
Use isFirstX to execute isFirst but die 'isFirst' instead of returning undef
Return the specified node if it is last under its parent and optionally has the specified context, else return undef
Use isLastNonBlank to skip a (rare) initial blank text CDATA. Use isLastNonBlankX to die rather then receive a returned undef or false result.
ok -p $a eq <<END; <a> <b> <c id="42" match="mm"/> </b> <d> <e/> </d> </a> END ok $a->go(q(d))->isLast;
Use isLastX to execute isLast but die 'isLast' instead of returning undef
Return the specified node if it is the only node under its parent (and ancestors) ignoring any surrounding blank text.
my $x = Data::Edit::Xml::new(<<END)->first->first; <a id="aa"><b id="bb"><c id="cc"/></b></a> END ok $x->isOnlyChild; ok $x->isOnlyChild(qw(c)); ok $x->isOnlyChild(qw(c b)); ok $x->isOnlyChild(qw(c b a));
Use isOnlyChildX to execute isOnlyChild but die 'isOnlyChild' instead of returning undef
Confirm that this node is empty, that is: this node has no content, not even a blank string of text. To test for blank nodes, see isAllBlankText.
my $x = Data::Edit::Xml::new(<<END); <a> </a> END ok $x->isEmpty; my $x = Data::Edit::Xml::new(<<END)->first->first; <a id="aa"><b id="bb"><c id="cc"/></b></a> END ok $x->isEmpty;
Use isEmptyX to execute isEmpty but die 'isEmpty' instead of returning undef
Confirm that the string representing the tags at the level below this node match a regular expression where each pair of tags is separated by a single space. Use contentAsTags to visualize the tags at the next level.
Parameter Description 1 $node Node 2 $re Regular expression 3 @context Optional context.
my $x = Data::Edit::Xml::new(<<END); <a> <b> <c/><d/><e/><f/><g/> </b> </a> END ok $x->go(q(b))->over(qr(d.+e));
Use overX to execute over but die 'over' instead of returning undef
Confirm that the string representing the tags at the level below this node match a regular expression where each pair of tags have two spaces between them and the first tag is preceded by a space and the last tag is followed by a space. This arrangement simplifies the regular expression used to detect combinations like p+ q? . Use contentAsTags2 to visualize the tags at the next level.
my $x = Data::Edit::Xml::new(<<END); <a> <b> <c/><d/><e/><f/><g/> </b> </a> END ok $x->go(q(b))->over2(qr(\A c d e f g \Z)); ok $x->go(q(b))->contentAsTags eq q(c d e f g) ;
Use over2X to execute over2 but die 'over2' instead of returning undef
Confirm that the string representing the tags following this node matches a regular expression where each pair of tags is separated by a single space. Use contentAfterAsTags to visualize these tags.
my $x = Data::Edit::Xml::new(<<END); <a> <b> <c/><d/><e/><f/><g/> </b> </a> END ok $x->go(qw(b e))->matchAfter (qr(\Af g\Z));
Use matchAfterX to execute matchAfter but die 'matchAfter' instead of returning undef
Confirm that the string representing the tags following this node matches a regular expression where each pair of tags have two spaces between them and the first tag is preceded by a space and the last tag is followed by a space. This arrangement simplifies the regular expression used to detect combinations like p+ q? Use contentAfterAsTags2 to visualize these tags.
my $x = Data::Edit::Xml::new(<<END); <a> <b> <c/><d/><e/><f/><g/> </b> </a> END ok $x->go(qw(b e))->matchAfter2 (qr(\A f g \Z));
Use matchAfter2X to execute matchAfter2 but die 'matchAfter2' instead of returning undef
Confirm that the string representing the tags preceding this node matches a regular expression where each pair of tags is separated by a single space. Use contentBeforeAsTags to visualize these tags.
my $x = Data::Edit::Xml::new(<<END); <a> <b> <c/><d/><e/><f/><g/> </b> </a> END ok $x->go(qw(b e))->matchBefore (qr(\Ac d\Z));
Use matchBeforeX to execute matchBefore but die 'matchBefore' instead of returning undef
Confirm that the string representing the tags preceding this node matches a regular expression where each pair of tags have two spaces between them and the first tag is preceded by a space and the last tag is followed by a space. This arrangement simplifies the regular expression used to detect combinations like p+ q? Use contentBeforeAsTags2 to visualize these tags.
my $x = Data::Edit::Xml::new(<<END); <a> <b> <c/><d/><e/><f/><g/> </b> </a> END ok $x->go(qw(b e))->matchBefore2(qr(\A c d \Z));
Use matchBefore2X to execute matchBefore2 but die 'matchBefore2' instead of returning undef
Return a list representing the path to a node which can then be reused by get to retrieve the node as long as the structure of the parse tree has not changed along the path.
my $x = Data::Edit::Xml::new(<<END); <a id='a1'> <b id='b1'> <c id='c1'/> <c id='c2'/> <d id='d1'> <e id='e1'/> </d> <c id='c3'/> <c id='c4'/> <d id='d2'> <e id='e2'/> </d> <c id='c5'/> <c id='c6'/> </b> </a> END is_deeply [$x->go(qw(b d 1 e))->path], [qw(b d 1 e)]; $x->by(sub {ok $x->go($_->path) == $_});
Return a string representing the path to a node
ok -z $a eq <<END; <a id="1"> <b id="2"> <c id="3"> <e id="4"/> </c> <d id="5"> <e id="6"/> </d> <c id="7"> <d id="8"> <e id="9"/> </d> </c> <d id="10"> <e id="11"/> </d> <c id="12"> <d id="13"> <e id="14"/> </d> </c> </b> </a> END ok $a->findByNumber(9)->pathString eq 'b c 1 d e';
Move around in the parse tree
Parameter Description 1 $node Node 2 @path Search specification.
my $x = Data::Edit::Xml::new(my $s = <<END); <aa> <a> <b/> <c id="1"/><c id="2"/><c id="3"/><c id="4"/> <d/> </a> </aa> END ok $x->go(qw(a c)) ->id == 1; ok $x->go(qw(a c -2))->id == 3; ok $x->go(qw(a c *)) == 4; ok 1234 == join '', map {$_->id} $x->go(qw(a c *));
Use goX to execute go but die 'go' instead of returning undef
Return an array of all the nodes with the specified tag below the specified node.
Parameter Description 1 $node Node 2 $tag Tag.
my $x = Data::Edit::Xml::new(<<END); <a> <b id="b1"><c id="1"/></b> <d id="d1"><c id="2"/></d> <e id="e1"><c id="3"/></e> <b id="b2"><c id="4"/></b> <d id="d2"><c id="5"/></d> <e id="e2"><c id="6"/></e> </a> END is_deeply [map{-u $_} $x->c(q(d))], [qw(d1 d2)];
Find nodes that are first amongst their siblings.
Return the first node below this node optionally checking its context.
Parameter Description 1 $node Node 2 @context Optional context.
Use firstNonBlank to skip a (rare) initial blank text CDATA. Use firstNonBlankX to die rather then receive a returned undef or false result.
my $a = Data::Edit::Xml::new(<<END); <a id="11"> <b id="12"> <c id="13"/> <d id="14"/> <b id="15"> <c id="16"/> <d id="17"/> <e id="18"/> <f id="19"/> <g id="20"/> </b> <f id="21"/> <g id="22"/> </b> <b id="23"> <c id="24"/> <d id="25"/> <b id="26"> <c id="27"/> <d id="28"/> <e id="29"/> <f id="30"/> <g id="31"/> </b> <f id="32"/> <g id="33"/> </b> </a> END ok $a->go(q(b))->first->id == 13; ok $a->go(q(b))->first(qw(c b a)); ok !$a->go(q(b))->first(qw(b a));
Use firstX to execute first but die 'first' instead of returning undef
Return the first node if it is a text node otherwise undef
ok -p $a eq <<END; <a>AA <b/> BB <c/> CC <d/> <e/> <f/> DD <g/> HH </a> END ok $a->firstText; ok !$a->go(qw(c))->firstText;
Use firstTextX to execute firstText but die 'firstText' instead of returning undef
Return a list of the first instance of each specified tag encountered in a post-order traversal from the specified node or a hash of all first instances if no tags are specified.
Parameter Description 1 $node Node 2 @tags Tags to search for.
my $a = Data::Edit::Xml::new(<<END); <a id="11"> <b id="12"> <c id="13"/> <d id="14"/> <b id="15"> <c id="16"/> <d id="17"/> <e id="18"/> <f id="19"/> <g id="20"/> </b> <f id="21"/> <g id="22"/> </b> <b id="23"> <c id="24"/> <d id="25"/> <b id="26"> <c id="27"/> <d id="28"/> <e id="29"/> <f id="30"/> <g id="31"/> </b> <f id="32"/> <g id="33"/> </b> </a> END my %f = $a->firstBy; ok $f{b}->id == 12;
Return a list of the first instance of each specified tag encountered in a pre-order traversal from the specified node or a hash of all first instances if no tags are specified.
my %f = $a->firstDown; ok $f{b}->id == 15;
Return the first node matching one of the named tags under the specified node.
ok $a->prettyStringCDATA eq <<'END'; <a><CDATA> </CDATA> <A/> <CDATA> </CDATA> <C/> <CDATA> </CDATA> <E/> <CDATA> </CDATA> <G/> <CDATA> </CDATA> </a> END ok $a->firstIn(qw(b B c C))->tag eq qq(C);
Use firstInX to execute firstIn but die 'firstIn' instead of returning undef
Return the specified node if it is first in its index and optionally at the specified context else undef
ok -z $a eq <<END; <a id="1"> <b id="2"> <c id="3"> <e id="4"/> </c> <d id="5"> <e id="6"/> </d> <c id="7"> <d id="8"> <e id="9"/> </d> </c> <d id="10"> <e id="11"/> </d> <c id="12"> <d id="13"> <e id="14"/> </d> </c> </b> </a> END ok $a->findByNumber (5)->firstInIndex; ok !$a->findByNumber(7) ->firstInIndex;
Use firstInIndexX to execute firstInIndex but die 'firstInIndex' instead of returning undef
Return an array of the nodes that are continuously first under their specified parent node and that match the specified list of tags.
my $a = Data::Edit::Xml::new(<<END); <a><b><c/><d/><d/><e/><d/><d/><c/></b></a> END is_deeply [qw(c d d)], [map {-t $_} $a->go(q(b))->firstOf(qw(c d))];
Return the first node encountered in the specified context in a depth first post-order traversal of the parse tree.
Parameter Description 1 $node Node 2 @context Array of tags specifying context.
my $x = Data::Edit::Xml::new(<<END); <a id="a1"> <b1 id="b1"> <c id="c1"> <d id="d1">DD11</d> <e id="e1">EE11</e> </c> </b1> <b2 id="b2"> <c id="c2"> <d id="d2">DD22</d> <e id="e2">EE22</e> </c> </b2> <b3 id="b3"> <c id="c3"> <d id="d3">DD33</d> <e id="e3">EE33</e> </c> </b3> </a> END ok $x->firstContextOf(qw(d c)) ->id eq qq(d1); ok $x->firstContextOf(qw(e c b2)) ->id eq qq(e2); ok $x->firstContextOf(qw(CDATA d c b2))->string eq qq(DD22);
Use firstContextOfX to execute firstContextOf but die 'firstContextOf' instead of returning undef
Return the first sibling of the specified node in the optional context else undef
my $a = Data::Edit::Xml::new(<<END); <a id="11"> <b id="12"> <c id="13"/> <d id="14"/> <b id="15"> <c id="16"/> <d id="17"/> <e id="18"/> <f id="19"/> <g id="20"/> </b> <f id="21"/> <g id="22"/> </b> <b id="23"> <c id="24"/> <d id="25"/> <b id="26"> <c id="27"/> <d id="28"/> <e id="29"/> <f id="30"/> <g id="31"/> </b> <f id="32"/> <g id="33"/> </b> </a> END ok $a->go(qw(b b))->firstSibling->id == 13;
Use firstSiblingX to execute firstSibling but die 'firstSibling' instead of returning undef
Find nodes that are last amongst their siblings.
Return the last node below this node optionally checking its context.
Use lastNonBlank to skip a (rare) initial blank text CDATA. Use lastNonBlankX to die rather then receive a returned undef or false result.
my $a = Data::Edit::Xml::new(<<END); <a id="11"> <b id="12"> <c id="13"/> <d id="14"/> <b id="15"> <c id="16"/> <d id="17"/> <e id="18"/> <f id="19"/> <g id="20"/> </b> <f id="21"/> <g id="22"/> </b> <b id="23"> <c id="24"/> <d id="25"/> <b id="26"> <c id="27"/> <d id="28"/> <e id="29"/> <f id="30"/> <g id="31"/> </b> <f id="32"/> <g id="33"/> </b> </a> END ok $a->go(q(b))->last ->id == 22; ok $a->go(q(b))->last(qw(g b a)); ok !$a->go(q(b))->last(qw(b a)); ok !$a->go(q(b))->last(qw(b a));
Use lastX to execute last but die 'last' instead of returning undef
Return the last node if it is a text node otherwise undef
ok -p $a eq <<END; <a>AA <b/> BB <c/> CC <d/> <e/> <f/> DD <g/> HH </a> END ok $a->lastText; ok !$a->go(qw(c))->lastText;
Use lastTextX to execute lastText but die 'lastText' instead of returning undef
Return a list of the last instance of each specified tag encountered in a post-order traversal from the specified node or a hash of all first instances if no tags are specified.
my $a = Data::Edit::Xml::new(<<END); <a id="11"> <b id="12"> <c id="13"/> <d id="14"/> <b id="15"> <c id="16"/> <d id="17"/> <e id="18"/> <f id="19"/> <g id="20"/> </b> <f id="21"/> <g id="22"/> </b> <b id="23"> <c id="24"/> <d id="25"/> <b id="26"> <c id="27"/> <d id="28"/> <e id="29"/> <f id="30"/> <g id="31"/> </b> <f id="32"/> <g id="33"/> </b> </a> END my %l = $a->lastBy; ok $l{b}->id == 23;
Return a list of the last instance of each specified tag encountered in a pre-order traversal from the specified node or a hash of all first instances if no tags are specified.
my %l = $a->lastDown; ok $l{b}->id == 26;
Return the last node matching one of the named tags under the specified node.
ok $a->prettyStringCDATA eq <<'END'; <a><CDATA> </CDATA> <A/> <CDATA> </CDATA> <C/> <CDATA> </CDATA> <E/> <CDATA> </CDATA> <G/> <CDATA> </CDATA> </a> END ok $a->lastIn(qw(e E f F))->tag eq qq(E);
Use lastInX to execute lastIn but die 'lastIn' instead of returning undef
Return an array of the nodes that are continuously last under their specified parent node and that match the specified list of tags.
my $a = Data::Edit::Xml::new(<<END); <a><b><c/><d/><d/><e/><d/><d/><c/></b></a> END is_deeply [qw(d d c)], [map {-t $_} $a->go(q(b))->lastOf (qw(c d))];
Return the specified node if it is last in its index and optionally at the specified context else undef
ok -z $a eq <<END; <a id="1"> <b id="2"> <c id="3"> <e id="4"/> </c> <d id="5"> <e id="6"/> </d> <c id="7"> <d id="8"> <e id="9"/> </d> </c> <d id="10"> <e id="11"/> </d> <c id="12"> <d id="13"> <e id="14"/> </d> </c> </b> </a> END ok $a->findByNumber(10)->lastInIndex; ok !$a->findByNumber(7) ->lastInIndex;
Use lastInIndexX to execute lastInIndex but die 'lastInIndex' instead of returning undef
Return the last node encountered in the specified context in a depth first reverse pre-order traversal of the parse tree.
my $x = Data::Edit::Xml::new(<<END); <a id="a1"> <b1 id="b1"> <c id="c1"> <d id="d1">DD11</d> <e id="e1">EE11</e> </c> </b1> <b2 id="b2"> <c id="c2"> <d id="d2">DD22</d> <e id="e2">EE22</e> </c> </b2> <b3 id="b3"> <c id="c3"> <d id="d3">DD33</d> <e id="e3">EE33</e> </c> </b3> </a> END ok $x-> lastContextOf(qw(d c)) ->id eq qq(d3); ok $x-> lastContextOf(qw(e c b2 )) ->id eq qq(e2); ok $x-> lastContextOf(qw(CDATA e c b2))->string eq qq(EE22);
Use lastContextOfX to execute lastContextOf but die 'lastContextOf' instead of returning undef
Return the last sibling of the specified node in the optional context else undef
my $a = Data::Edit::Xml::new(<<END); <a id="11"> <b id="12"> <c id="13"/> <d id="14"/> <b id="15"> <c id="16"/> <d id="17"/> <e id="18"/> <f id="19"/> <g id="20"/> </b> <f id="21"/> <g id="22"/> </b> <b id="23"> <c id="24"/> <d id="25"/> <b id="26"> <c id="27"/> <d id="28"/> <e id="29"/> <f id="30"/> <g id="31"/> </b> <f id="32"/> <g id="33"/> </b> </a> END ok $a->go(qw(b b))->lastSibling ->id == 22;
Use lastSiblingX to execute lastSibling but die 'lastSibling' instead of returning undef
Find sibling nodes after the specified node.
Return the node next to the specified node, optionally checking its context.
Use nextNonBlank to skip a (rare) initial blank text CDATA. Use nextNonBlankX to die rather then receive a returned undef or false result.
my $a = Data::Edit::Xml::new(<<END); <a id="11"> <b id="12"> <c id="13"/> <d id="14"/> <b id="15"> <c id="16"/> <d id="17"/> <e id="18"/> <f id="19"/> <g id="20"/> </b> <f id="21"/> <g id="22"/> </b> <b id="23"> <c id="24"/> <d id="25"/> <b id="26"> <c id="27"/> <d id="28"/> <e id="29"/> <f id="30"/> <g id="31"/> </b> <f id="32"/> <g id="33"/> </b> </a> END ok $a->go(qw(b b e))->next ->id == 19; ok $a->go(qw(b b e))->next(qw(f b b a)); ok !$a->go(qw(b b e))->next(qw(f b a));
Use nextX to execute next but die 'next' instead of returning undef
Return the next node if it is a text node otherwise undef
ok -p $a eq <<END; <a>AA <b/> BB <c/> CC <d/> <e/> <f/> DD <g/> HH </a> END ok $a->go(qw(c))->nextText->text eq q(CC); ok !$a->go(qw(e))->nextText;
Use nextTextX to execute nextText but die 'nextText' instead of returning undef
Return the nearest sibling after the specified node that matches one of the named tags or undef if there is no such sibling node.
ok $a->prettyStringCDATA eq <<'END'; <a><CDATA> </CDATA> <A/> <CDATA> </CDATA> <C/> <CDATA> </CDATA> <E/> <CDATA> </CDATA> <G/> <CDATA> </CDATA> </a> END ok $a->firstIn(qw(b B c C))->nextIn(qw(A G))->tag eq qq(G);
Use nextInX to execute nextIn but die 'nextIn' instead of returning undef
Step forwards as far as possible while remaining on nodes with the specified tags. In scalar context return the last such node reached or the starting node if no such steps are possible. In array context return the start node and any following matching nodes.
Parameter Description 1 $node Start node 2 @tags Tags identifying nodes that can be step on to context.
ok -p $a eq <<END; <a> <b> <c id="1"/> <d id="2"/> <c id="3"/> <d id="4"/> <e id="5"/> </b> </a> END ok $c->id == 1; ok $e->id == 5; ok $c->nextOn(qw(d)) ->id == 2; ok $c->nextOn(qw(c d))->id == 4; ok $e->nextOn(qw(c d)) == $e;
Find sibling nodes before the specified node.
Return the node before the specified node, optionally checking its context.
Use prevNonBlank to skip a (rare) initial blank text CDATA. Use prevNonBlankX to die rather then receive a returned undef or false result.
my $a = Data::Edit::Xml::new(<<END); <a id="11"> <b id="12"> <c id="13"/> <d id="14"/> <b id="15"> <c id="16"/> <d id="17"/> <e id="18"/> <f id="19"/> <g id="20"/> </b> <f id="21"/> <g id="22"/> </b> <b id="23"> <c id="24"/> <d id="25"/> <b id="26"> <c id="27"/> <d id="28"/> <e id="29"/> <f id="30"/> <g id="31"/> </b> <f id="32"/> <g id="33"/> </b> </a> END ok $a->go(qw(b b e))->prev ->id == 17; ok $a->go(qw(b b e))->prev(qw(d b b a)); ok !$a->go(qw(b b e))->prev(qw(d b a));
Use prevX to execute prev but die 'prev' instead of returning undef
Return the previous node if it is a text node otherwise undef
ok -p $a eq <<END; <a>AA <b/> BB <c/> CC <d/> <e/> <f/> DD <g/> HH </a> END ok $a->go(qw(c))->prevText->text eq q(BB); ok !$a->go(qw(e))->prevText;
Use prevTextX to execute prevText but die 'prevText' instead of returning undef
Return the nearest sibling node before the specified node which matches one of the named tags or undef if there is no such sibling node.
ok $a->prettyStringCDATA eq <<'END'; <a><CDATA> </CDATA> <A/> <CDATA> </CDATA> <C/> <CDATA> </CDATA> <E/> <CDATA> </CDATA> <G/> <CDATA> </CDATA> </a> END ok $a->lastIn(qw(e E f F))->prevIn(qw(A G))->tag eq qq(A);
Use prevInX to execute prevIn but die 'prevIn' instead of returning undef
Step backwards as far as possible while remaining on nodes with the specified tags. In scalar context return the last such node reached or the starting node if no such steps are possible. In array context return the start node and any preceding matching nodes.
ok -p $a eq <<END; <a> <b> <c id="1"/> <d id="2"/> <c id="3"/> <d id="4"/> <e id="5"/> </b> </a> END ok $c->id == 1; ok $e->id == 5; ok $e->prevOn(qw(d)) ->id == 4; ok $e->prevOn(qw(c d)) == $c;
Methods for moving up the parse tree from a node.
Return the parent of the current node optionally checking the context of the specified node first or return undef if the specified node is the root of the parse tree.
Parameter Description 1 $node Start node 2 @tags Optional tags identifying context.
ok -z $a eq <<END; <a id="1"> <b id="2"> <c id="3"> <b id="4"> <b id="5"> <b id="6"> <b id="7"> <c id="8"/> </b> </b> </b> </b> </c> </b> </a> END ok $a->findByNumber(8)->up(qw(c b b)) ->number == 7;
Use upX to execute up but die 'up' instead of returning undef
Move up starting from the specified node as long as the tag of each node matches the specified regular expression. Return the last matching node if there is one else undef.
Parameter Description 1 $node Start node 2 $re Tags identifying context.
ok -z $a eq <<END; <a id="1"> <b id="2"> <c id="3"> <b id="4"> <b id="5"> <b id="6"> <b id="7"> <c id="8"/> </b> </b> </b> </b> </c> </b> </a> END ok $a->findByNumber(7)->upWhile(qr(a|b))->number == 4; ok !$a->findByNumber(8)->upWhile(qr(a|b)); ok $a->findByNumber(8)->upWhile(qr(b|c))->number == 2;
Use upWhileX to execute upWhile but die 'upWhile' instead of returning undef
Return the first ancestral node that matches the specified context.
Parameter Description 1 $node Start node 2 @tags Tags identifying context.
$a->numberTree; ok -z $a eq <<END; <a id="1"> <b id="2"> <c id="3"> <b id="4"> <b id="5"> <b id="6"> <b id="7"> <c id="8"/> </b> </b> </b> </b> </c> </b> </a> END ok $a->findByNumber(8)->upTo(qw(b c)) ->number == 4;
Use upToX to execute upTo but die 'upTo' instead of returning undef
Edit the data in the parse tree and change the structure of the parse tree by wrapping and unwrapping nodes, by replacing nodes, by cutting and pasting nodes, by concatenating nodes, by splitting nodes, by adding new text nodes or swapping nodes.
Parameter Description 1 $node Node 2 $name New name 3 @context Optional context.
my $a = Data::Edit::Xml::new('<a/>'); $a->change(qq(b)); ok -s $a eq '<b/>';
Use changeX to execute change but die 'change' instead of returning undef
Move nodes around in the parse tree by cutting and pasting them.
Parameter Description 1 $node Node to cut out 2 @context Optional context
ok -p $a eq <<END; <a id="aa"> <b id="bb"> <c id="cc"/> </b> </a> END my $c = $a->go(qw(b c))->cut; ok -p $a eq <<END; <a id="aa"> <b id="bb"/> </a> END
Place a cut out or new node at the front of the content of the specified node and return the new node.
Parameter Description 1 $old Original node 2 $new New node 3 @context Optional context.
ok -p $a eq <<END; <a id="aa"> <b id="bb"> <c id="cc"/> </b> </a> END my $c = $a->go(qw(b c))->cut; $a->putFirst($c); ok -p $a eq <<END; <a id="aa"> <c id="cc"/> <b id="bb"/> </a> END
ok -p $a eq <<END; <a id="aa"> <c id="cc"/> <b id="bb"/> </a> END $a->putLast($a->go(qw(c))->cut); ok -p $a eq <<END; <a id="aa"> <b id="bb"/> <c id="cc"/> </a> END
Place a cut out or new node just after the specified node and return the new node.
ok -p $a eq <<END; <a id="aa"> <b id="bb"/> <c id="cc"/> </a> END $a->go(qw(c))->putNext($a->go(q(b))->cut); ok -p $a eq <<END; <a id="aa"> <c id="cc"/> <b id="bb"/> </a> END
Place a cut out or new node just before the specified node and return the new node.
ok -p $a eq <<END; <a id="aa"> <c id="cc"/> <b id="bb"/> </a> END $a->go(qw(c))->putPrev($a->go(q(b))->cut); ok -p $a eq <<END; <a id="aa"> <b id="bb"/> <c id="cc"/> </a> END
Join consecutive nodes
Concatenate two successive nodes and return the target node.
Parameter Description 1 $target Target node to replace 2 $source Node to concatenate 3 @context Optional context of $target
my $s = <<END; <a> <b> <A/> <B/> </b> <c> <C/> <D/> </c> </a> END my $a = Data::Edit::Xml::new($s); $a->go(q(b))->concatenate($a->go(q(c))); my $t = <<END; <a> <b> <A/> <B/> <C/> <D/> </b> </a> END ok $t eq -p $a;
Concatenate preceding and following nodes as long as they have the same tag as the specified node and return the specified node.
Parameter Description 1 $node Concatenate around this node 2 @context Optional context.
ok -p $a eq <<END; <a> <b> <c id="1"/> </b> <b> <c id="2"/> </b> <b> <c id="3"/> </b> <b> <c id="4"/> </b> </a> END $a->go(qw(b 3))->concatenateSiblings; ok -p $a eq <<END; <a> <b> <c id="1"/> <c id="2"/> <c id="3"/> <c id="4"/> </b> </a> END
Add text to the parse tree.
Add a new text node first under a parent and return the new text node.
Parameter Description 1 $node The parent node 2 $text The string to be added which might contain unparsed Xml as well as text 3 @context Optional context.
ok -p $x eq <<END; <a id="aa"> <b id="bb"> <c id="cc"/> </b> </a> END $x->go(qw(b c))->putFirstAsText("<d id=\"dd\">DDDD</d>"); ok -p $x eq <<END; <a id="aa"> <b id="bb"> <c id="cc"><d id="dd">DDDD</d></c> </b> </a> END
Add a new text node last under a parent and return the new text node.
ok -p $x eq <<END; <a id="aa"> <b id="bb"> <c id="cc"><d id="dd">DDDD</d></c> </b> </a> END $x->go(qw(b c))->putLastAsText("<e id=\"ee\">EEEE</e>"); ok -p $x eq <<END; <a id="aa"> <b id="bb"> <c id="cc"><d id="dd">DDDD</d><e id="ee">EEEE</e></c> </b> </a> END
Add a new text node following this node and return the new text node.
ok -p $x eq <<END; <a id="aa"> <b id="bb"> <c id="cc"><d id="dd">DDDD</d><e id="ee">EEEE</e></c> </b> </a> END $x->go(qw(b c))->putNextAsText("<n id=\"nn\">NNNN</n>"); ok -p $x eq <<END; <a id="aa"> <b id="bb"> <c id="cc"><d id="dd">DDDD</d><e id="ee">EEEE</e></c> <n id="nn">NNNN</n> </b> </a> END
Add a new text node following this node and return the new text node
ok -p $x eq <<END; <a id="aa"> <b id="bb"> <c id="cc"><d id="dd">DDDD</d><e id="ee">EEEE</e></c> <n id="nn">NNNN</n> </b> </a> END $x->go(qw(b c))->putPrevAsText("<p id=\"pp\">PPPP</p>"); ok -p $x eq <<END; <a id="aa"> <b id="bb"><p id="pp">PPPP</p> <c id="cc"><d id="dd">DDDD</d><e id="ee">EEEE</e></c> <n id="nn">NNNN</n> </b> </a> END
Break nodes out of nodes or push them back
Concatenate the nodes following and preceding the start node, unwrapping nodes whose tag matches the start node and return the start node. To concatenate only the preceding nodes, use breakInBackwards, to concatenate only the following nodes, use breakInForwards.
Parameter Description 1 $start The start node 2 @context Optional context.
ok -p $a eq <<END; <a> <d/> <b> <c/> <c/> </b> <e/> <b> <c/> <c/> </b> <d/> </a> END $a->go(qw(b 1))->breakIn; ok -p $a eq <<END; <a> <b> <d/> <c/> <c/> <e/> <c/> <c/> <d/> </b> </a> END
Concatenate the nodes following the start node, unwrapping nodes whose tag matches the start node and return the start node in the manner of breakIn.
Parameter Description 1 $start The start node 2 @context Optional context..
ok -p $a eq <<END; <a> <d/> <b> <c/> <c/> </b> <e/> <b> <c/> <c/> </b> <d/> </a> END $a->go(q(b))->breakInForwards; ok -p $a eq <<END; <a> <d/> <b> <c/> <c/> <e/> <c/> <c/> <d/> </b> </a> END
Concatenate the nodes preceding the start node, unwrapping nodes whose tag matches the start node and return the start node in the manner of breakIn.
ok -p $a eq <<END; <a> <d/> <b> <c/> <c/> </b> <e/> <b> <c/> <c/> </b> <d/> </a> END $a->go(qw(b 1))->breakInBackwards; ok -p $a eq <<END; <a> <b> <d/> <c/> <c/> <e/> <c/> <c/> </b> <d/> </a> END
Lift child nodes with the specified tags under the specified parent node splitting the parent node into clones and return the cut out original node.
Parameter Description 1 $parent The parent node 2 @tags The tags of the modes to be broken out.
my $A = Data::Edit::Xml::new("<a><b><d/><c/><c/><e/><c/><c/><d/></b></a>"); $a->go(q(b))->breakOut($a, qw(d e)); ok -p $a eq <<END; <a> <d/> <b> <c/> <c/> </b> <e/> <b> <c/> <c/> </b> <d/> </a> END
Replace nodes in the parse tree with nodes or text
Replace a node (and all its content) with a new node (and all its content) and return the new node. If the node to be replaced is the root of the parse tree then no action is taken other then returning the new node.
Parameter Description 1 $old Old node 2 $new New node 3 @context Optional context..
my $x = Data::Edit::Xml::new(qq(<a><b><c id="cc"/></b></a>)); $x->go(qw(b c))->replaceWith($x->newTag(qw(d id dd))); ok -s $x eq '<a><b><d id="dd"/></b></a>';
Replace a node (and all its content) with a new text node and return the new node.
Parameter Description 1 $old Old node 2 $text Text of new node 3 @context Optional context.
my $x = Data::Edit::Xml::new(qq(<a><b><c id="cc"/></b></a>)); $x->go(qw(b c))->replaceWithText(qq(BBBB)); ok -s $x eq '<a><b>BBBB</b></a>';
Replace a node (and all its content) with a new blank text node and return the new node.
Parameter Description 1 $old Old node 2 @context Optional context.
my $x = Data::Edit::Xml::new(qq(<a><b><c id="cc"/></b></a>)); $x->go(qw(b c))->replaceWithBlank; ok -s $x eq '<a><b> </b></a>';
Replace the content of a specified target node with the contents of the specified source nodes removing the content from each source node and return the target node.
Parameter Description 1 $node Target node 2 @nodes Source nodes
my $a = Data::Edit::Xml::new(<<END); <a> <b> <b1/> <b2/> </b> <c> <c1/> <c2/> </c> <d> <d1/> <d2/> </d> </a> END my ($b, $c, $d) = $a->contents; $d->replaceContentWithMovedContent($c, $b); ok -p $a eq <<END; <a> <b/> <c/> <d> <c1/> <c2/> <b1/> <b2/> </d> </a> END my $a = Data::Edit::Xml::new(<<END); <a> <d> <b> <b1/> <b2/> </b> <c> <c1/> <c2/> </c> </d> </a> END my ($d) = $a->contents; my ($b, $c) = $d->contents; $d->replaceContentWithMovedContent($c, $b); ok -p $a eq <<END; <a> <d> <c1/> <c2/> <b1/> <b2/> </d> </a> END
Replace the content of a node with the specified nodes and return the replaced content
Parameter Description 1 $node Node whose content is to be replaced 2 @content New content
my $x = Data::Edit::Xml::new(qq(<a><b/><c/></a>)); $x->replaceContentWith(map {$x->newTag($_)} qw(B C)); ok -s $x eq '<a><B/><C/></a>';
Replace the content of a node with the specified texts and return the replaced content
Parameter Description 1 $node Node whose content is to be replaced 2 @text Texts to form new content
my $x = Data::Edit::Xml::new(qq(<a><b/><c/></a>)); $x->replaceContentWithText(qw(b c)); ok -s $x eq '<a>bc</a>';
Swap nodes both singly and in blocks
Swap two nodes optionally checking that the first node is in the specified context and return the first node.
Parameter Description 1 $first First node 2 $second Second node 3 @context Optional context
ok <<END eq -p $x; <x> <a a="1" b="2"/> <b/> <c a="1" b="3" c="4"/> </x> END $a->swap($c); ok <<END eq -p $x; <x> <c a="1" b="3" c="4"/> <b/> <a a="1" b="2"/> </x> END
Use swapX to execute swap but die 'swap' instead of returning undef
Wrap and unwrap nodes to alter the depth of the parse tree
Parameter Description 1 $old Node 2 $tag Tag for the new node or tag 3 %attributes Attributes for the new node or tag.
ok -p $x eq <<END; <a> <b> <c id="11"/> </b> </a> END $x->go(qw(b c))->wrapWith(qw(C id 1)); ok -p $x eq <<END; <a> <b> <C id="1"> <c id="11"/> </C> </b> </a> END
Wrap the original node in a sequence of new nodes forcing the original node down - deepening the parse tree - return the array of wrapping nodes.
Parameter Description 1 $node Node to wrap 2 @tags Tags to wrap the node with - with the uppermost tag rightmost.
my $c = Data::Edit::Xml::newTree("c", id=>33); my ($b, $a) = $c->wrapUp(qw(b a)); ok -p $a eq <<'END'; <a> <b> <c id="33"/> </b> </a> END
Wrap the content of the specified node in a sequence of new nodes forcing the original node up - deepening the parse tree - return the array of wrapping nodes.
my $a = Data::Edit::Xml::newTree("a", id=>33); my ($b, $c) = $a->wrapDown(qw(b c)); ok -p $a eq <<END; <a id="33"> <b> <c/> </b> </a> END
Wrap the content of a node in a new node: the original node then contains just the new node which, in turn, contains all the content of the original node.
Returns the new wrapped node.
Parameter Description 1 $old Node 2 $tag Tag for new node 3 %attributes Attributes for new node.
ok -p $x eq <<END; <a> <b> <c/> <c/> <c/> </b> </a> END $x->go(q(b))->wrapContentWith(qw(D id DD)); ok -p $x eq <<END; <a> <b> <D id="DD"> <c/> <c/> <c/> </D> </b> </a> END ok -p $a eq <<END; <a> <b id="1"/> <c id="2"/> <d id="3"/> <c id="4"/> <d id="5"/> <e id="6"/> <b id="7"/> <c id="8"/> <d id="9"/> <f id="10"/> </a> END
Wrap all the nodes from the start node to the end node with a new node with the specified tag and attributes and return the new node. Return undef if the start and end nodes are not siblings - they must have the same parent for this method to work.
Parameter Description 1 $start Start node 2 $end End node 3 $tag Tag for the wrapping node 4 %attributes Attributes for the wrapping node
my $x = Data::Edit::Xml::new(my $s = <<END); <aa> <a> <b/> <c id="1"/><c id="2"/><c id="3"/><c id="4"/> <d/> </a> </aa> END $x->go(qw(a c))->wrapTo($x->go(qw(a c -1)), qq(C), id=>1234); ok -p $x eq <<END; <aa> <a> <b/> <C id="1234"> <c id="1"/> <c id="2"/> <c id="3"/> <c id="4"/> </C> <d/> </a> </aa> END my $C = $x->go(qw(a C)); $C->wrapTo($C, qq(D)); ok -p $x eq <<END; <aa> <a> <b/> <D> <C id="1234"> <c id="1"/> <c id="2"/> <c id="3"/> <c id="4"/> </C> </D> <d/> </a> </aa> END ok -p $a eq <<END; <a> <b> <D id="DD"> <c id="0"/> <c id="1"/> </D> <E id="EE"> <c id="2"/> </E> <F id="FF"> <c id="3"/> </F> </b> </a> END
Use wrapToX to execute wrapTo but die 'wrapTo' instead of returning undef
Parameter Description 1 $end End node 2 $start Start node 3 $tag Tag for the wrapping node 4 @attr Attributes for the wrapping node
my $a = Data::Edit::Xml::new(my $s = <<END); <a> <b> <c id="0"/><c id="1"/><c id="2"/><c id="3"/> </b> </a> END my $b = $a->first; my @c = $b->contents; $c[1]->wrapFrom($c[0], qw(D id DD)); ok -p $a eq <<END; <a> <b> <D id="DD"> <c id="0"/> <c id="1"/> </D> <c id="2"/> <c id="3"/> </b> </a> END
Use wrapFromX to execute wrapFrom but die 'wrapFrom' instead of returning undef
Parameter Description 1 $node Node to unwrap 2 @context Optional context.
ok -s $x eq "<a>A<b> c </b>B</a>"; $b->unwrap; ok -s $x eq "<a>A c B</a>";
Use unwrapX to execute unwrap but die 'unwrap' instead of returning undef
Unwrap all the non text nodes below a specified node adding a leading and a trailing space to prevent unwrapped content from being elided and return the specified node else undef if not in the optional context.
ok -p $x eq <<END; <a> <b> <c> <d>DD</d> EE <f>FF</f> </c> </b> </a> END $x->go(qw(b))->unwrapContentsKeepingText; ok -p $x eq <<END; <a> <b> DD EE FF </b> </a> END
Use unwrapContentsKeepingTextX to execute unwrapContentsKeepingText but die 'unwrapContentsKeepingText' instead of returning undef
The children of each node.
Return a list of all the nodes contained by this node or an empty list if the node is empty or not in the optional context.
Use the @context parameter to provide an optional context for this method as understood by method at . If a context is supplied and the node specified by the first parameter is not in this context then this method returns an empty list () immediately.
my $x = Data::Edit::Xml::new(<<END); <a> <b id="b1"><c id="1"/></b> <d id="d1"><c id="2"/></d> <e id="e1"><c id="3"/></e> <b id="b2"><c id="4"/></b> <d id="d2"><c id="5"/></d> <e id="e2"><c id="6"/></e> </a> END is_deeply [map{-u $_} $x->contents], [qw(b1 d1 e1 b2 d2 e2)];
Return a list of all the sibling nodes following this node or an empty list if this node is last or not in the optional context.
my $x = Data::Edit::Xml::new(<<END); <a> <b> <c/><d/><e/><f/><g/> </b> </a> END ok 'f g' eq join ' ', map {$_->tag} $x->go(qw(b e))->contentAfter;
Return a list of all the sibling nodes preceding this node or an empty list if this node is last or not in the optional context.
my $x = Data::Edit::Xml::new(<<END); <a> <b> <c/><d/><e/><f/><g/> </b> </a> END ok 'c d' eq join ' ', map {$_->tag} $x->go(qw(b e))->contentBefore;
Return a string containing the tags of all the child nodes of this node separated by single spaces or the empty string if the node is empty or undef if the node does not match the optional context. Use over to test the sequence of tags with a regular expression.
my $x = Data::Edit::Xml::new(<<END); <a> <b> <c/><d/><e/><f/><g/> </b> </a> END ok $x->go(q(b))->contentAsTags eq 'c d e f g';
Use contentAsTagsX to execute contentAsTags but die 'contentAsTags' instead of returning undef
Return a string containing the tags of all the child nodes of this node separated by two spaces with a single space preceding the first tag and a single space following the last tag or the empty string if the node is empty or undef if the node does not match the optional context. Use over2 to test the sequence of tags with a regular expression. Use over2 to test the sequence of tags with a regular expression.
ok $x->go(q(b))->contentAsTags2 eq q( c d e f g );
Use contentAsTags2X to execute contentAsTags2 but die 'contentAsTags2' instead of returning undef
Return a string containing the tags of all the sibling nodes following this node separated by single spaces or the empty string if the node is empty or undef if the node does not match the optional context. Use matchAfter to test the sequence of tags with a regular expression.
my $x = Data::Edit::Xml::new(<<END); <a> <b> <c/><d/><e/><f/><g/> </b> </a> END ok 'f g' eq join ' ', map {$_->tag} $x->go(qw(b e))->contentAfter; ok $x->go(qw(b e))->contentAfterAsTags eq 'f g';
Return a string containing the tags of all the sibling nodes following this node separated by two spaces with a single space preceding the first tag and a single space following the last tag or the empty string if the node is empty or undef if the node does not match the optional context. Use matchAfter2 to test the sequence of tags with a regular expression.
my $x = Data::Edit::Xml::new(<<END); <a> <b> <c/><d/><e/><f/><g/> </b> </a> END ok $x->go(qw(b e))->contentAfterAsTags2 eq q( f g );
Return a string containing the tags of all the sibling nodes preceding this node separated by single spaces or the empty string if the node is empty or undef if the node does not match the optional context. Use matchBefore to test the sequence of tags with a regular expression.
my $x = Data::Edit::Xml::new(<<END); <a> <b> <c/><d/><e/><f/><g/> </b> </a> END ok 'c d' eq join ' ', map {$_->tag} $x->go(qw(b e))->contentBefore; ok $x->go(qw(b e))->contentBeforeAsTags eq 'c d';
Return a string containing the tags of all the sibling nodes preceding this node separated by two spaces with a single space preceding the first tag and a single space following the last tag or the empty string if the node is empty or undef if the node does not match the optional context. Use matchBefore2 to test the sequence of tags with a regular expression.
my $x = Data::Edit::Xml::new(<<END); <a> <b> <c/><d/><e/><f/><g/> </b> </a> END ok $x->go(qw(b e))->contentBeforeAsTags2 eq q( c d );
Return the index of a node in its parent's content.
my $a = Data::Edit::Xml::new(<<END); <a id="11"> <b id="12"> <c id="13"/> <d id="14"/> <b id="15"> <c id="16"/> <d id="17"/> <e id="18"/> <f id="19"/> <g id="20"/> </b> <f id="21"/> <g id="22"/> </b> <b id="23"> <c id="24"/> <d id="25"/> <b id="26"> <c id="27"/> <d id="28"/> <e id="29"/> <f id="30"/> <g id="31"/> </b> <f id="32"/> <g id="33"/> </b> </a> END ok $a->go(qw(b 1 b))->id == 26; ok $a->go(qw(b 1 b))->position == 2;
Return the index of a node in its parent index.
my $a = Data::Edit::Xml::new(<<END); <a id="11"> <b id="12"> <c id="13"/> <d id="14"/> <b id="15"> <c id="16"/> <d id="17"/> <e id="18"/> <f id="19"/> <g id="20"/> </b> <f id="21"/> <g id="22"/> </b> <b id="23"> <c id="24"/> <d id="25"/> <b id="26"> <c id="27"/> <d id="28"/> <e id="29"/> <f id="30"/> <g id="31"/> </b> <f id="32"/> <g id="33"/> </b> </a> END ok $a->go(qw(b 1))->id == 23; ok $a->go(qw(b 1))->index == 1;
Return the count of the number of the specified tag types present immediately under a node or a hash {tag} = count for all the tags present under the node if no names are specified.
Parameter Description 1 $node Node 2 @names Possible tags immediately under the node.
is_deeply {$a->first->present}, {c=>2, d=>2, e=>1};
Return the specified node if this node is a text node, optionally in the specified context, else return undef.
Parameter Description 1 $node Node to test 2 @context Optional context
ok $a->prettyStringCDATA eq <<END; <a> <b><CDATA> </CDATA></b> </a> END ok $b->first->isText; ok $b->first->isText(qw(b a));
Use isTextX to execute isText but die 'isText' instead of returning undef
Return the specified node if this node is a text node, the first node under its parent and that the parent is optionally in the specified context, else return undef.
Parameter Description 1 $node Node to test 2 @context Optional context for parent
my $x = Data::Edit::Xml::new(<<END); <x> <a>aaa <b>bbb</b> ccc <d>ddd</d> eee </a> </x> END my $a = $x->first; my ($ta, $b, $tc, $d, $te) = $a->contents; ok $ta ->isFirstText(qw(a x)); ok $b->first->isFirstText(qw(b a x)); ok $b->prev ->isFirstText(qw(a x)); ok $d->last ->isFirstText(qw(d a x));
Use isFirstTextX to execute isFirstText but die 'isFirstText' instead of returning undef
Return the specified node if this node is a text node, the last node under its parent and that the parent is optionally in the specified context, else return undef.
my $x = Data::Edit::Xml::new(<<END); <x> <a>aaa <b>bbb</b> ccc <d>ddd</d> eee </a> </x> END ok $d->next ->isLastText (qw(a x)); ok $d->last ->isLastText (qw(d a x)); ok $te ->isLastText (qw(a x));
Use isLastTextX to execute isLastText but die 'isLastText' instead of returning undef
Returns an array of regular expression matches in the text of the specified node if it is text node and it matches the specified regular expression and optionally has the specified context otherwise returns an empty array
Parameter Description 1 $node Node to test 2 $re Regular expression 3 @context Optional context
my $x = Data::Edit::Xml::new(<<END); <a> <b> <c>CDECD</c> </b> </a> END my $c = $x->go(qw(b c))->first; is_deeply [qw(E)], [$c->matchesText(qr(CD(.)CD))]; ok !$c->matchesText(qr(\AD)); ok $c->matchesText(qr(\AC), qw(c b a)); ok !$c->matchesText(qr(\AD), qw(c b a));
Use matchesTextX to execute matchesText but die 'matchesText' instead of returning undef
Return the specified node if this node is a text node, optionally in the specified context, and contains nothing other than whitespace else return undef. See also: isAllBlankText
ok $a->prettyStringCDATA eq <<END; <a> <b><CDATA> </CDATA></b> </a> END ok $b->first->isBlankText;
Use isBlankTextX to execute isBlankText but die 'isBlankText' instead of returning undef
Return the specified node if this node, optionally in the specified context, does not contain anything or if it does contain something it is all whitespace else return undef. See also: bitsNodeTextBlank
my $a = Data::Edit::Xml::new(<<END); <a> <b> <c> <z/> </c> </b> <d/> </a> END $a->by(sub{$_->replaceWithBlank(qw(z))}); my ($b, $c, $d) = $a->firstBy(qw(b c d)); ok $c->isAllBlankText; ok $c->isAllBlankText(qw(c b a)); ok !$c->isAllBlankText(qw(c a));
Use isAllBlankTextX to execute isAllBlankText but die 'isAllBlankText' instead of returning undef
Return a bit string that shows if there are any non text nodes, text nodes or blank text nodes under a node. An empty string is returned if there are no child nodes.
Parameter Description 1 $node Node to test.
ok $x->prettyStringCDATA eq <<END; <a> <b> <C/> </b> <c> <D/> <CDATA> E </CDATA> </c> <d> <F/> <CDATA> </CDATA> <H/> </d> <e/> </a> END ok '100' eq -B $x; ok '100' eq -B $x->go(q(b)); ok '110' eq -B $x->go(q(c)); ok '111' eq -B $x->go(q(d)); ok !-B $x->go(qw(e));
Number and verify the order of nodes.
Find the node with the specified number as made visible by prettyStringNumbered in the parse tree containing the specified node and return the found node or undef if no such node exists.
Parameter Description 1 $node Node in the parse tree to search 2 $number Number of the node required.
$a->numberTree; ok $a->prettyStringNumbered eq <<END; <a id="1"> <b id="2"> <A id="3"/> <B id="4"/> </b> <c id="5"> <C id="6"/> <D id="7"/> </c> </a> END ok q(D) eq -t $a->findByNumber(7);
Use findByNumberX to execute findByNumber but die 'findByNumber' instead of returning undef
Find the nodes with the specified numbers as made visible by prettyStringNumbered in the parse tree containing the specified node and return the found nodes in a list with undef for nodes that do not exist.
Parameter Description 1 $node Node in the parse tree to search 2 @numbers Numbers of the nodes required.
$a->numberTree; ok $a->prettyStringNumbered eq <<END; <a id="1"> <b id="2"> <A id="3"/> <B id="4"/> </b> <c id="5"> <C id="6"/> <D id="7"/> </c> </a> END is_deeply [map {-t $_} $a->findByNumbers(1..3)], [qw(a b A)];
Number the nodes in a parse tree in pre-order so they are numbered in the same sequence that they appear in the source. You can see the numbers by printing the tree with prettyStringNumbered().
Parameter Description 1 $node Node
$a->numberTree; ok -z $a eq <<END; <a id="1"> <b id="2"> <c id="42" match="mm"/> </b> <d id="4"> <e id="5"/> </d> </a> END
Return the first node if the first node is above the second node optionally checking that the first node is in the specified context otherwise return undef
my $x = Data::Edit::Xml::new(<<END); <a id='a1'> <b id='b1'> <c id='c1'/> <c id='c2'/> <d id='d1'> <e id='e1'/> </d> <c id='c3'/> <c id='c4'/> <d id='d2'> <e id='e2'/> </d> <c id='c5'/> <c id='c6'/> </b> </a> END ok $b->id eq 'b1'; ok $e->id eq "e1"; ok $E->id eq "e2"; ok $b->above($e); ok !$E->above($e);
Use aboveX to execute above but die 'above' instead of returning undef
Return the first node if the first node is below the second node optionally checking that the first node is in the specified context otherwise return undef
my $x = Data::Edit::Xml::new(<<END); <a id='a1'> <b id='b1'> <c id='c1'/> <c id='c2'/> <d id='d1'> <e id='e1'/> </d> <c id='c3'/> <c id='c4'/> <d id='d2'> <e id='e2'/> </d> <c id='c5'/> <c id='c6'/> </b> </a> END ok $d->id eq 'd1'; ok $e->id eq "e1"; ok !$d->below($e);
Use belowX to execute below but die 'below' instead of returning undef
Return the first node if it occurs after the second node in the parse tree optionally checking that the first node is in the specified context or else undef if the node is above, below or before the target.
my $x = Data::Edit::Xml::new(<<END); <a id='a1'> <b id='b1'> <c id='c1'/> <c id='c2'/> <d id='d1'> <e id='e1'/> </d> <c id='c3'/> <c id='c4'/> <d id='d2'> <e id='e2'/> </d> <c id='c5'/> <c id='c6'/> </b> </a> END ok $c->id eq 'c1'; ok $e->id eq "e1"; ok $e->after($c);
Use afterX to execute after but die 'after' instead of returning undef
Return the first node if it occurs before the second node in the parse tree optionally checking that the first node is in the specified context or else undef if the node is above, below or before the target.
my $x = Data::Edit::Xml::new(<<END); <a id='a1'> <b id='b1'> <c id='c1'/> <c id='c2'/> <d id='d1'> <e id='e1'/> </d> <c id='c3'/> <c id='c4'/> <d id='d2'> <e id='e2'/> </d> <c id='c5'/> <c id='c6'/> </b> </a> END ok $e->id eq "e1"; ok $E->id eq "e2"; ok $e->before($E);
Use beforeX to execute before but die 'before' instead of returning undef
Return the first node that is out of the specified order when performing a pre-ordered traversal of the parse tree.
Parameter Description 1 $node Node 2 @nodes Following nodes.
my $x = Data::Edit::Xml::new(<<END); <a id='a1'> <b id='b1'> <c id='c1'/> <c id='c2'/> <d id='d1'> <e id='e1'/> </d> <c id='c3'/> <c id='c4'/> <d id='d2'> <e id='e2'/> </d> <c id='c5'/> <c id='c6'/> </b> </a> END ok $b->id eq 'b1'; ok $c->id eq 'c1'; ok $d->id eq 'd1'; ok $e->id eq "e1"; ok $e->disordered($c )->id eq "c1"; ok $b->disordered($c, $e, $d)->id eq "d1"; ok !$c->disordered($e);
Find the most recent common ancestor of the specified nodes or undef if there is no common ancestor.
Parameter Description 1 $node Node 2 @nodes @nodes
ok -z $a eq <<END; <a id="1"> <b id="2"> <c id="3"> <e id="4"/> </c> <d id="5"> <e id="6"/> </d> <c id="7"> <d id="8"> <e id="9"/> </d> </c> <d id="10"> <e id="11"/> </d> <c id="12"> <d id="13"> <e id="14"/> </d> </c> </b> </a> END my ($b, $e, @n) = $a->findByNumbers(2, 4, 6, 9); ok $e == $e->commonAncestor; ok $e == $e->commonAncestor($e); ok $b == $e->commonAncestor($b); ok $b == $e->commonAncestor(@n);
Use commonAncestorX to execute commonAncestor but die 'commonAncestor' instead of returning undef
Return the first node if the specified nodes are all in order when performing a pre-ordered traversal of the parse tree else return undef
my $x = Data::Edit::Xml::new(<<END); <a id='a1'> <b id='b1'> <c id='c1'/> <c id='c2'/> <d id='d1'> <e id='e1'/> </d> <c id='c3'/> <c id='c4'/> <d id='d2'> <e id='e2'/> </d> <c id='c5'/> <c id='c6'/> </b> </a> END ok $e->id eq "e1"; ok $E->id eq "e2"; ok $e->ordered($E); ok !$E->ordered($e); ok $e->ordered($e); ok $e->ordered;
Use orderedX to execute ordered but die 'ordered' instead of returning undef
Analyze and generate tables of contents
Table of Contents number the nodes in a parse tree.
Parameter Description 1 $node Node 2 @match Optional list of tags to descend into e3se all tags will be descended into
ok $a->prettyStringNumbered eq <<END; <a id="1"> <b id="2"> <A id="3"/> <B id="4"/> </b> <c id="5"> <C id="6"/> <D id="7"/> </c> </a> END my $t = $a->tocNumbers(); is_deeply {map {$_=>$t->{$_}->tag} keys %$t}, "1" =>"b", "1 1"=>"A", "1 2"=>"B", "2" =>"c", "2 1"=> "C", "2 2"=>"D" }
Label nodes so that they can be cross referenced and linked by Data::Edit::Xml::Lint
Add the named labels to the specified node and return that node.
Parameter Description 1 $node Node in parse tree 2 @labels Names of labels to add.
ok $x->stringReplacingIdsWithLabels eq '<a><b><c/></b></a>'; my $b = $x->go(q(b)); ok $b->countLabels == 0; $b->addLabels(1..2); $b->addLabels(3..4); ok $x->stringReplacingIdsWithLabels eq '<a><b id="1, 2, 3, 4"><c/></b></a>';
Return the count of the number of labels at a node.
ok $x->stringReplacingIdsWithLabels eq '<a><b><c/></b></a>'; my $b = $x->go(q(b)); ok $b->countLabels == 0; $b->addLabels(1..2); $b->addLabels(3..4); ok $x->stringReplacingIdsWithLabels eq '<a><b id="1, 2, 3, 4"><c/></b></a>'; ok $b->countLabels == 4;
Return the names of all the labels set on a node.
ok $x->stringReplacingIdsWithLabels eq '<a><b><c/></b></a>'; my $b = $x->go(q(b)); ok $b->countLabels == 0; $b->addLabels(1..2); $b->addLabels(3..4); ok $x->stringReplacingIdsWithLabels eq '<a><b id="1, 2, 3, 4"><c/></b></a>'; is_deeply [1..4], [$b->getLabels];
Delete the specified labels in the specified node or all labels if no labels have are specified and return that node.
Parameter Description 1 $node Node in parse tree 2 @labels Names of the labels to be deleted
ok $x->stringReplacingIdsWithLabels eq '<a><b id="1, 2, 3, 4"><c id="1, 2, 3, 4"/></b></a>'; $b->deleteLabels(1,4) for 1..2; ok $x->stringReplacingIdsWithLabels eq '<a><b id="2, 3"><c id="1, 2, 3, 4"/></b></a>';
Copy all the labels from the source node to the target node and return the source node.
Parameter Description 1 $source Source node 2 $target Target node.
ok $x->stringReplacingIdsWithLabels eq '<a><b id="1, 2, 3, 4"><c/></b></a>'; $b->copyLabels($c) for 1..2; ok $x->stringReplacingIdsWithLabels eq '<a><b id="1, 2, 3, 4"><c id="1, 2, 3, 4"/></b></a>';
Move all the labels from the source node to the target node and return the source node.
ok $x->stringReplacingIdsWithLabels eq '<a><b id="2, 3"><c id="1, 2, 3, 4"/></b></a>'; $b->moveLabels($c) for 1..2; ok $x->stringReplacingIdsWithLabels eq '<a><b><c id="1, 2, 3, 4"/></b></a>';
Operator access to methods use the assign versions to avoid 'useless use of operator in void context' messages. Use the non assign versions to return the results of the underlying method call. Thus '/' returns the wrapping node, whilst '/=' does not. Assign operators always return their left hand side even though the corresponding method usually returns the modification on the right.
-B: bitsNodeTextBlank
-b: isAllBlankText
-c: context
-e: prettyStringEnd
-f: first node
-g: getAttr
-l: last node
-M: number
-o: contentAsTags
-p: prettyString
-s: string
-S : stringNode
-T : isText
-t : tag
-u: id
-W: unWrap
-w: stringQuoted
-X: cut
-z: prettyStringNumbered. Dangerous operations which might destroy information are in upper case.
Parameter Description 1 $node Node 2 $op Monadic operator.
my $a = Data::Edit::Xml::new(<<END); <a> <b><c>ccc</c></b> <d><e>eee</e></d> </a> END my $a = Data::Edit::Xml::new(<<END); <a> <b> <c id="42" match="mm"/> </b> <d> <e/> </d> </a> END my ($c, $b, $e, $d) = $a->byList; ok -A $c eq q(c id="42" match="mm"); ok -b $e; ok -c $e eq q(e d a); ok -f $b eq $c; ok -l $a eq $d; ok -O $a, q( b d ); ok -o $a, q(b d); ok -w $a eq q('<a><b><c id="42" match="mm"/></b><d><e/></d></a>'); ok -p $a eq <<END; <a> <b> <c id="42" match="mm"/> </b> <d> <e/> </d> </a> END ok -s $a eq '<a><b><c id="42" match="mm"/></b><d><e/></d></a>'; ok -t $a eq 'a'; $a->numberTree; ok -z $a eq <<END; <a id="1"> <b id="2"> <c id="42" match="mm"/> </b> <d id="4"> <e id="5"/> </d> </a> END
Statistics describing the parse tree.
Return the count of the number of instances of the specified tags under the specified node, either by tag in array context or in total in scalar context.
my $x = Data::Edit::Xml::new(<<END); <a> </a> END ok $x->count == 0;
Count the number of tags in a parse tree.
Parameter Description 1 $node Parse tree.
ok -p $a eq <<END; <a id="aa"> <b id="bb"> <c id="cc"/> </b> </a> END ok $a->countTags == 3;
Return a reference to a hash showing the number of instances of each tag on and below the specified node.
Parameter Description 1 $node Node 2 $count Count of tags so far.
my $x = Data::Edit::Xml::new(<<END); <a A="A" B="B" C="C"> <b B="B" C="C"> <c C="C"> </c> <c/> </b> <b C="C"> <c/> </b> </a> END is_deeply $x->countTagNames, { a => 1, b => 2, c => 3 };
Return a reference to a hash showing the number of instances of each attribute on and below the specified node.
Parameter Description 1 $node Node 2 $count Count of attributes so far.
my $x = Data::Edit::Xml::new(<<END); <a A="A" B="B" C="C"> <b B="B" C="C"> <c C="C"> </c> <c/> </b> <b C="C"> <c/> </b> </a> END is_deeply $x->countAttrNames, { A => 1, B => 2, C => 4 };
Return a reference to a hash showing the number of instances of each attribute value on and below the specified node.
my $x = Data::Edit::Xml::new(<<END); <a A="A" B="B" C="C"> <b B="B" C="C"> <c C="C"> </c> <c/> </b> <b C="C"> <c/> </b> </a> END is_deeply $x->countAttrValues, { A => 1, B => 2, C => 4 };
Count instances of outputclass attributes
Parameter Description 1 $node Node 2 $count Count so far.
my $a = Data::Edit::Xml::newTree("a", id=>1, class=>2, href=>3, outputclass=>4); is_deeply { 4 => 1 }, $a->countOutputClasses;
Provide a specification to select change reason comments to be inserted as text into a parse tree. A specification can be either:
changeReasonCommentSelectionSpecification = {ccc=>1, ddd=>1}; changeReasonCommentSelectionSpecification = undef;
Data::Edit::Xml::changeReasonCommentSelectionSpecification
Insert a comment consisting of a code and an optional reason as text into the parse tree to indicate the location of changes to the parse tree. As such comments tend to become very numerous, only comments whose codes matches the specification provided in changeReasonCommentSelectionSpecification are accepted for insertion. Subsequently these comments can be easily located using:
grep -nr "<!--code"
on the file containing a printed version of the parse tree. Please note that these comments will be removed if the output file is reparsed.
Returns the specified node.
Parameter Description 1 $node Node being changed 2 $code Reason code 3 $reason Optional text description of change
my $a = Data::Edit::Xml::new("<a><b/></a>"); my ($b) = $a->contents; changeReasonCommentSelectionSpecification = {ccc=>1, ddd=>1}; $b->putFirst(my $c = $b->newTag(q(c))); $c->crc($_) for qw(aaa ccc); ok <<END eq -p $a; <a> <b><!--ccc--> <c/> </b> </a> END changeReasonCommentSelectionSpecification = undef; $c->putFirst(my $d = $c->newTag(q(d))); $d->crc($_) for qw(aaa ccc); ok <<END eq -p $a; <a> <b><!--ccc--> <c> <d/> </c> </b> </a> END
Replace a node with a required cleanup node around the text of the replaced node with special characters replaced by symbols.
Parameter Description 1 $node Node 2 $id Optional id of required cleanup tag
my $a = Data::Edit::Xml::new(<<END); <a> <b> <c> ccc </c> </b> </a> END my ($b) = $a->contents; $b->requiredCleanUp(q(33)); ok -p $a eq <<END; <a><required-cleanup id="33"><b> <c> ccc </c> </b> </required-cleanup></a> END
Replace a node with a required cleanup message and return the new node
Parameter Description 1 $node Node to be replace 2 $text Clean up message
my $a = Data::Edit::Xml::new(<<END); <a> <b/> </a> END my ($b) = $a->contents; $b->replaceWithRequiredCleanUp(q(bb)); ok -p $a eq <<END; <a><required-cleanup>bb</required-cleanup></a> END
Methods useful for convertions to Dita.
Change the specified node to steps and its contents to cmd\step optionally only in the specified context.
Parameter Description 1 $list Node 2 @context Optional context
ok -p $a eq <<END; <dita> <ol> <li> <p>aaa</p> </li> <li> <p>bbb</p> </li> </ol> </dita> END $a->first->listToDitaSteps; ok -p $a eq <<END; <dita> <steps> <step> <cmd>aaa</cmd> </step> <step> <cmd>bbb</cmd> </step> </steps> </dita> END
Change the specified node to ol and its cmd\step content to li optionally only in the specified context.
Parameter Description 1 $steps Node 2 @context Optional context
ok -p $a eq <<END; <dita> <ol> <li> <p>aaa</p> </li> <li> <p>bbb</p> </li> </ol> </dita> END $a->first->ditaStepsToList; ok -p $a eq <<END; <dita> <ol> <li>aaa</li> <li>bbb</li> </ol> </dita> END
Make obvious changes to a parse tree to make it look more like Dita.
my $a = Data::Edit::Xml::new(<<END); <dita> <ol> <li><para>aaa</para></li> <li><para>bbb</para></li> </ol> </dita> END $a->ditaObviousChanges; ok -p $a eq <<END; <dita> <ol> <li> <p>aaa</p> </li> <li> <p>bbb</p> </li> </ol> </dita> END
Add xml headers for the dita document type indicated by the specified parse tree
Parameter Description 1 $node Node in parse tree
Debugging methods
Print the attributes of a node.
Parameter Description 1 $node Node whose attributes are to be printed.
my $x = Data::Edit::Xml::new(my $s = <<END); <a no="1" word="first"/> END ok $x->printAttributes eq qq( no="1" word="first");
Print the tag and attributes of a node.
Parameter Description 1 $node Node to be printed.
A debug version of go that returns additional information explaining any failure to reach the node identified by the path.
Returns ([reachable tag...], [possible tag...]) where:
the path elements successfully traversed;
the possibilities at the point where the path failed if it failed else undef.
my $a = Data::Edit::Xml::new(<<END); <a> <b> <c> <d/> </c> </b> </a> END my ($good, $possible) = $a->goFish(qw(b c D)); is_deeply $good, [qw(b c)]; is_deeply $possible, [q(d)];
Build a tree representation of the parsed XML which can be easily traversed to look for things.
Parameter Description 1 $parent The parent node 2 $parse The remaining parse
Remove a leaf node from the parse tree and make it into its own parse tree.
Parameter Description 1 $node Leaf node to disconnect.
Index the children of a node so that we can access them by tag and number.
Parameter Description 1 $node Node to index.
Merge multiple text segments and set parent and parser after changes to a node
Normalize whitespace, remove comments DOCTYPE and xml processors from a string
Parameter Description 1 $string String to normalize
Return a readable string representing a node of a parse tree and all the nodes below it as a here document
Post-order traversal of a parse tree or sub tree calling the specified sub within eval{} at each node and returning the specified starting node. The sub is passed references to the current node and all of its ancestors. The value of the current node is also made available via $_.
Parameter Description 1 $node Starting node 2 $sub Sub to call 3 @context Accumulated context.
Pre-order traversal of a parse tree or sub tree calling the specified sub within eval{} at each node and returning the specified starting node. The sub is passed references to the current node and all of its ancestors. The value of the current node is also made available via $_.
Pre-order traversal down through a parse tree or sub tree calling the specified sub within eval{} at each node and returning the specified starting node. The sub is passed references to the current node and all of its ancestors. The value of the current node is also made available via $_.
Ensure that this node has a number.
Topic type and corresponding body.
Parameter Description 1 $type Type from qw(bookmap concept reference task)
Print the attributes of a node replacing the id with the labels.
Check the parent pointers are correct in a parse tree.
Parameter Description 1 $x Parse tree.
Check that every node has a parser.
Replace new lines in a string with N to make testing easier.
Parameter Description 1 $s String.
1 above
2 aboveNonBlank
3 aboveNonBlankX
4 aboveX
5 addConditions
6 addLabels
7 after
8 afterNonBlank
9 afterNonBlankX
10 afterX
11 allConditions
12 allConditionsX
13 ancestry
14 anyCondition
15 anyConditionX
16 at
17 atOrBelow
18 atOrBelowX
19 attr
20 attrCount
21 attributes
22 attrs
23 atX
24 audience
25 before
26 beforeNonBlank
27 beforeNonBlankX
28 beforeX
29 below
30 belowNonBlank
31 belowNonBlankX
32 belowX
33 bitsNodeTextBlank
34 breakIn
35 breakInBackwards
36 breakInBackwardsNonBlank
37 breakInBackwardsNonBlankX
38 breakInForwards
39 breakInForwardsNonBlank
40 breakInForwardsNonBlankX
41 breakInNonBlank
42 breakInNonBlankX
43 breakOut
44 by
45 byList
46 byListNonBlank
47 byListNonBlankX
48 byReverse
49 byReverseList
50 byReverseListNonBlank
51 byReverseListNonBlankX
52 byReverseX
53 byX
54 byX2
55 byX22
56 byXNonBlank
57 byXNonBlankX
58 c
59 cdata
60 change
61 changeAttr
62 changeAttrValue
63 changeNonBlank
64 changeNonBlankX
65 changeReasonCommentSelectionSpecification
66 changeX
67 checkParentage
68 checkParser
69 class
70 clone
71 cloneNonBlank
72 cloneNonBlankX
73 commonAncestor
74 commonAncestorX
75 concatenate
76 concatenateNonBlank
77 concatenateNonBlankX
78 concatenateSiblings
79 concatenateSiblingsNonBlank
80 concatenateSiblingsNonBlankX
81 condition
82 conditionNonBlank
83 conditionNonBlankX
84 conditions
85 conditionX
86 containsSingleText
87 content
88 contentAfter
89 contentAfterAsTags
90 contentAfterAsTags2
91 contentAfterAsTags2NonBlank
92 contentAfterAsTags2NonBlankX
93 contentAfterAsTagsNonBlank
94 contentAfterAsTagsNonBlankX
95 contentAfterNonBlank
96 contentAfterNonBlankX
97 contentAsTags
98 contentAsTags2
99 contentAsTags2NonBlank
100 contentAsTags2NonBlankX
101 contentAsTags2X
102 contentAsTagsNonBlank
103 contentAsTagsNonBlankX
104 contentAsTagsX
105 contentBefore
106 contentBeforeAsTags
107 contentBeforeAsTags2
108 contentBeforeAsTags2NonBlank
109 contentBeforeAsTags2NonBlankX
110 contentBeforeAsTagsNonBlank
111 contentBeforeAsTagsNonBlankX
112 contentBeforeNonBlank
113 contentBeforeNonBlankX
114 contents
115 contentsNonBlank
116 contentsNonBlankX
117 context
118 copyAttrs
119 copyLabels
120 copyNewAttrs
121 count
122 countAttrNames
123 countAttrValues
124 countLabels
125 countOutputClasses
126 countTagNames
127 countTags
128 crc
129 cut
130 cutNonBlank
131 cutNonBlankX
132 data
133 deleteAttr
134 deleteAttrs
135 deleteConditions
136 deleteLabels
137 depth
138 diff
139 disconnectLeafNode
140 disordered
141 ditaObviousChanges
142 ditaStepsToList
143 ditaStepsToListNonBlank
144 ditaStepsToListNonBlankX
145 ditaTopicHeaders
146 down
147 downReverse
148 downReverseX
149 downX
150 downX2
151 downX22
152 downXNonBlank
153 downXNonBlankX
154 equals
155 equalsX
156 errorsFile
157 expandIncludes
158 findByNumber
159 findByNumbers
160 findByNumberX
161 first
162 firstBy
163 firstContextOf
164 firstContextOfX
165 firstDown
166 firstIn
167 firstInIndex
168 firstInIndexNonBlank
169 firstInIndexNonBlankX
170 firstInIndexX
171 firstInX
172 firstNonBlank
173 firstNonBlankX
174 firstOf
175 firstSibling
176 firstSiblingNonBlank
177 firstSiblingNonBlankX
178 firstSiblingX
179 firstText
180 firstTextNonBlank
181 firstTextNonBlankX
182 firstTextX
183 firstX
184 from
185 fromTo
186 getAttrs
187 getLabels
188 go
189 goFish
190 goX
191 guid
192 href
193 id
194 index
195 indexes
196 indexNode
197 input
198 inputFile
199 inputString
200 isAllBlankText
201 isAllBlankTextNonBlank
202 isAllBlankTextNonBlankX
203 isAllBlankTextX
204 isBlankText
205 isBlankTextNonBlank
206 isBlankTextNonBlankX
207 isBlankTextX
208 isEmpty
209 isEmptyNonBlank
210 isEmptyNonBlankX
211 isEmptyX
212 isFirst
213 isFirstNonBlank
214 isFirstNonBlankX
215 isFirstText
216 isFirstTextNonBlank
217 isFirstTextNonBlankX
218 isFirstTextX
219 isFirstX
220 isLast
221 isLastNonBlank
222 isLastNonBlankX
223 isLastText
224 isLastTextNonBlank
225 isLastTextNonBlankX
226 isLastTextX
227 isLastX
228 isOnlyChild
229 isOnlyChildNonBlank
230 isOnlyChildNonBlankX
231 isOnlyChildX
232 isText
233 isTextNonBlank
234 isTextNonBlankX
235 isTextX
236 labels
237 lang
238 last
239 lastBy
240 lastContextOf
241 lastContextOfX
242 lastDown
243 lastIn
244 lastInIndex
245 lastInIndexNonBlank
246 lastInIndexNonBlankX
247 lastInIndexX
248 lastInX
249 lastNonBlank
250 lastNonBlankX
251 lastOf
252 lastSibling
253 lastSiblingNonBlank
254 lastSiblingNonBlankX
255 lastSiblingX
256 lastText
257 lastTextNonBlank
258 lastTextNonBlankX
259 lastTextX
260 lastX
261 listConditions
262 listToDitaSteps
263 listToDitaStepsNonBlank
264 listToDitaStepsNonBlankX
265 matchAfter
266 matchAfter2
267 matchAfter2NonBlank
268 matchAfter2NonBlankX
269 matchAfter2X
270 matchAfterNonBlank
271 matchAfterNonBlankX
272 matchAfterX
273 matchBefore
274 matchBefore2
275 matchBefore2NonBlank
276 matchBefore2NonBlankX
277 matchBefore2X
278 matchBeforeNonBlank
279 matchBeforeNonBlankX
280 matchBeforeX
281 matchesText
282 matchesTextNonBlank
283 matchesTextNonBlankX
284 matchesTextX
285 moveAttrs
286 moveLabels
287 moveNewAttrs
288 navtitle
289 new
290 newTag
291 newText
292 newTree
293 next
294 nextIn
295 nextInX
296 nextNonBlank
297 nextNonBlankX
298 nextOn
299 nextText
300 nextTextNonBlank
301 nextTextNonBlankX
302 nextTextX
303 nextX
304 nn
305 normalizeWhiteSpace
306 number
307 numbering
308 numberNode
309 numbers
310 numberTree
311 opString
312 ordered
313 orderedX
314 otherprops
315 outputclass
316 over
317 over2
318 over2NonBlank
319 over2NonBlankX
320 over2X
321 overNonBlank
322 overNonBlankX
323 overX
324 parent
325 parse
326 parser
327 path
328 pathString
329 position
330 present
331 prettyString
332 prettyStringCDATA
333 prettyStringContent
334 prettyStringContentNumbered
335 prettyStringEnd
336 prettyStringNumbered
337 prev
338 prevIn
339 prevInX
340 prevNonBlank
341 prevNonBlankX
342 prevOn
343 prevText
344 prevTextNonBlank
345 prevTextNonBlankX
346 prevTextX
347 prevX
348 printAttributes
349 printAttributesReplacingIdsWithLabels
350 printNode
351 props
352 putFirst
353 putFirstAsText
354 putFirstAsTextNonBlank
355 putFirstAsTextNonBlankX
356 putFirstNonBlank
357 putFirstNonBlankX
358 putLast
359 putLastAsText
360 putLastAsTextNonBlank
361 putLastAsTextNonBlankX
362 putLastNonBlank
363 putLastNonBlankX
364 putNext
365 putNextAsText
366 putNextAsTextNonBlank
367 putNextAsTextNonBlankX
368 putNextNonBlank
369 putNextNonBlankX
370 putPrev
371 putPrevAsText
372 putPrevAsTextNonBlank
373 putPrevAsTextNonBlankX
374 putPrevNonBlank
375 putPrevNonBlankX
376 reindexNode
377 renameAttr
378 renameAttrValue
379 renew
380 renewNonBlank
381 renewNonBlankX
382 replaceContentWith
383 replaceContentWithMovedContent
384 replaceContentWithText
385 replaceSpecialChars
386 replaceWith
387 replaceWithBlank
388 replaceWithBlankNonBlank
389 replaceWithBlankNonBlankX
390 replaceWithNonBlank
391 replaceWithNonBlankX
392 replaceWithRequiredCleanUp
393 replaceWithText
394 replaceWithTextNonBlank
395 replaceWithTextNonBlankX
396 requiredCleanUp
397 restore
398 restoreX
399 save
400 set
401 setAttr
402 string
403 stringContent
404 stringNode
405 stringQuoted
406 stringReplacingIdsWithLabels
407 stringWithConditions
408 style
409 swap
410 swapNonBlank
411 swapNonBlankX
412 swapX
413 tag
414 text
415 through
416 throughX
417 to
418 tocNumbers
419 topicTypeAndBody
420 tree
421 type
422 unwrap
423 unwrapContentsKeepingText
424 unwrapContentsKeepingTextNonBlank
425 unwrapContentsKeepingTextNonBlankX
426 unwrapContentsKeepingTextX
427 unwrapNonBlank
428 unwrapNonBlankX
429 unwrapX
430 up
431 upNonBlank
432 upNonBlankX
433 upTo
434 upToX
435 upWhile
436 upWhileX
437 upX
438 wrapContentWith
439 wrapDown
440 wrapFrom
441 wrapFromX
442 wrapTo
443 wrapToX
444 wrapUp
445 wrapWith
446 xmlHeader
This module is written in 100% Pure Perl and, thus, it is easy to read, comprehend, use, modify and install via cpan:
sudo cpan install Data::Edit::Xml
philiprbrenan@gmail.com
http://www.appaapps.com
Copyright (c) 2016-2018 Philip R Brenan.
This module is free software. It may be used, redistributed and/or modified under the same terms as Perl itself.
To install Data::Edit::Xml, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Data::Edit::Xml
CPAN shell
perl -MCPAN -e shell install Data::Edit::Xml
For more information on module installation, please visit the detailed CPAN module installation guide.