Name

Data::Edit::Xml - Edit data held in xml format

Synopsis

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 if $_ -> at(qw(c b a))});

In chained exit style:

$a -> byX(sub {$_ -> at(qw(c b a)) -> cut});

In operator style:

$a x= sub {--$_ if $_ <= [qw(c b a)]};

Print the transformed parse tree

say STDERR -p $a;

to get:

<a>
  <b/>
  <d>
    <c/>
  </d>
</a>

Bullets to unordered list

To transform a series of bullets in to <ul> <li> ... first 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, changing bullets to <li> and either wrapping with <ul> or appending to a previous <ul>

$a->by(sub                                                                    # Bulleted list to <ul>
 {if ($_->at(qw(p)) and my $t = $_->containsSingleText)                       # <p> with single text
   {if ($t->text =~ m/\A\x{2022}/s)                                           # Starting with a bullet
     {$t->text =~ s(\A.\s*)()s;                                               # Remove bullet and leading spaces
      $_->change(qw(li));                                                     # <p> to <li>
      if (my $p = $_->prev)                                                   # Previous element
       {$p->at(qw(ul)) ? $p->putLast($_->cut) : $_->wrapWith(qw(ul));         # Put in preceding list or create a new list
       }
     }
   }
 });

To get:

ok -p $a eq <<END;
<a>
<li>Minimum 1 number
</li>
<ul>
  <li>No leading, trailing, or embedded spaces
  </li>
  <li>Not case-sensitive
  </li>
</ul>
</a>
END

DocBook to Dita

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>
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>

Description

The following sections describe the methods in each functional area of this module. For an alphabetic listing of all methods by name see Index.

Immediately useful methods

These methods are the ones most likely to be of immediate useful 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.

attr :lvalue

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. The value of the current node is also made available via $_.

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

prev

Return the node previous to the specified 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.

Construction

Create a parse tree, either by parsing a file or string, or, node by node, or, from another parse tree'

File or String

Construct a parse tree from a file or a string

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.

1  $fileNameOrString  File name or string

Example:

my $x = Data::Edit::Xml::new(<<END);
<a>
  <b>
    <c id="42"/>
  </b>
  <d>
    <e/>
  </d>
</a>
END

ok -p $x eq <<END;
<a>
  <b>
    <c id="42"/>
  </b>
  <d>
    <e/>
  </d>
</a>
END

This is a static method and so should be invoked as:

Data::Edit::Xml::new

content :lvalue

Content of command: the nodes immediately below this node in the order in which they appeared in the source text, see also "Contents".

numbers :lvalue

Nodes by number.

attributes :lvalue

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'.

conditions :lvalue

Conditional strings attached to a node, see "Conditions".

indexes :lvalue

Indexes to sub commands by tag in the order in which they appeared in the source text.

labels :lvalue

The labels attached to a node to provide addressability from other nodes, see: "Labels".

errorsFile :lvalue

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.

inputFile :lvalue

Source file of the parse if this is the parser root node. Use this parameter to explicitly set the file to be parsed.

input :lvalue

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.

inputString :lvalue

Source string of the parse if this is the parser root node. Use this parameter to explicitly set the string to be parsed.

number :lvalue

Number of this node, see findByNumber.

numbering :lvalue

Last number used to number a node in this parse tree.

parent :lvalue

Parent node of this node or undef if the oarser root node. See also "Traversal" and "Navigation". Consider as read only.

parser :lvalue

Parser details: the root node of a tree is the parse node for that tree. Consider as read only.

tag :lvalue

Tag name for this node, see also "Traversal" and "Navigation". Consider as read only.

text :lvalue

Text of this node but only if it is a text node, i.e. the tag is cdata() <=> "isText" is true.

cdata()

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.

Example:

ok Data::Edit::Xml::cdata eq q(CDATA);

parse($)

Parse input xml specified via: inputFile, input or inputString.

1  $parser  Parser created by L</new>

Example:

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

Node by Node

Construct a parse tree node by node.

newText($$)

Create a new text node.

1  undef  Any reference to this package
2  $text  Content of new text node

Example:

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

newTag($$%)

Create a new non text node.

1  undef        Any reference to this package
2  $command     The tag for the node
3  %attributes  Attributes as a hash.

Example:

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

newTree($%)

Create a new tree.

1  $command     The name of the root node in the tree
2  %attributes  Attributes of the root node in the tree as a hash.

Example:

my $x = Data::Edit::Xml::newTree("a", id=>1, class=>"aa");

ok -s $x eq '<a class="aa" id="1"/>';

replaceSpecialChars($)

Replace < > " with &lt; &gt; &quot; Larry Wall's excellent Xml parser unfortunately replaces &lt; &gt; &quot; &amp; 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 &amp; or leave it as is: consequently you might have to examine the instances of & in your output text and guess based on the context.

1  $string  String to be edited.

Example:

ok Data::Edit::Xml::replaceSpecialChars(q(<">)) eq "&lt;&quot;&gt;";

Parse tree

Construct a parse tree from another parse tree

renew($)

Returns a renewed copy of the parse tree: use this method if you have added nodes via the "Put as text" methods and wish to add them to the parse tree

1  $node  Parse tree.

Example:

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)

clone($)

Return a clone of the parse tree: the parse tree is cloned without converting it to string and reparsing it so this method will not renew any nodes added as text.

1  $node  Parse tree.

Example:

my $a = Data::Edit::Xml::new("<a> </a>");

my $A = $a->clone;

ok -s $A eq q(<a/>);

ok $a->equals($A);

equals($$)

Return the first node if the two parse trees are equal, else undef if they are not equal.

1  $node1  Parse tree 1
2  $node2  Parse tree 2.

Example:

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

save($$)

Save a copy of the parse tree to a file which can be restored and return the saved node.

1  $node  Parse tree
2  $file  File.

Example:

$y->save($f);

my $Y = Data::Edit::Xml::restore($f);

ok $Y->equals($y);

restore($)

Return a parse tree from a copy saved in a file by "save".

1  $file  File

Example:

$y->save($f);

my $Y = Data::Edit::Xml::restore($f);

ok $Y->equals($y);

Use restoreX to execute restore but die 'restore' instead of returning undef

This is a static method and so should be invoked as:

Data::Edit::Xml::restore

Print

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

Pretty print 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

1  $node   Start node
2  $depth  Optional depth.

Example:

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;

prettyStringNumbered($$)

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.

1  $node   Start node
2  $depth  Optional depth.

Example:

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

prettyStringShowingCDATA($$)

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>.

1  $node   Start node
2  $depth  Optional depth.

Example:

if (1)

$a->first->replaceWithBlank;

ok $a->prettyStringShowingCDATA eq <<END;
<a><CDATA> </CDATA>
</a>
END

my $a = Data::Edit::Xml::new("<a>1<A/>2<B/>3<C/>4<D/>5<E/>6<F/>7<G/>8<H/>9</a>");

map {$_->replaceWithBlank} grep {$_->isText}               $a->contents;

map {$_->cut}              grep {$_->tag =~ m/\A[BDFH]\Z/} $a->contents;

ok $a->prettyStringShowingCDATA eq <<'END';
<a><CDATA> </CDATA>
    <A/>
<CDATA>  </CDATA>
    <C/>
<CDATA>  </CDATA>
    <E/>
<CDATA>  </CDATA>
    <G/>
<CDATA>  </CDATA>
</a>
END

PrettyContentString($)

Return a readable string representing all the nodes below a node of a parse tree - infrequent use and so capitalized to avoid being presented as an option by Geany.

1  $node  Start node.

Example:

my $s = <<END;
<a>
  <b>
    <A/>
    <B/>
  </b>
  <c>
    <C/>
    <D/>
  </c>
</a>
END

ok $a->PrettyContentString eq <<END;
<b>
  <A/>
  <B/>
</b>
<c>
  <C/>
  <D/>
</c>
END

Dense

Print the parse tree.

string($)

Return a dense string representing a node of a parse tree and all the nodes below it. Or use -s $node

1  $node  Start node.

Example:

ok -p $x eq <<END;
<a>
  <b>
    <c id="42"/>
  </b>
  <d>
    <e/>
  </d>
</a>
END

ok -s $x eq '<a><b><c id="42"/></b><d><e/></d></a>';

stringQuoted($)

Return a quoted string representing a parse tree a node of a parse tree and all the nodes below it. Or use -o $node

1  $node  Start node

Example:

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>');

stringReplacingIdsWithLabels($)

Return a string representing the specified parse tree with the id attribute of each node set to the Labels attached to each node.

1  $node  Start node.

Example:

ok -r $x 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>';

stringContent($)

Return a string representing all the nodes below a node of a parse tree.

1  $node  Start node.

Example:

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>";

stringNode($)

Return a string representing a node showing the attributes, labels and node number

1  $node  Node.

Example:

ok -r $x eq '<a><b><c/></b></a>';

$b->addLabels(1..2);

$b->addLabels(3..4);

ok -r $x 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";

Conditions

Print a subset of the the parse tree determined by the conditions attached to it.

stringWithConditions($@)

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.

1  $node        Start node
2  @conditions  Conditions to be regarded as in effect.

Example:

my $x = Data::Edit::Xml::new(<<END);
<a>
  <b/>
  <c/>
</a>
END

my $b = $x >= 'b';

my $c = $x >= 'c';

$b->addConditions(qw(bb BB));

$c->addConditions(qw(cc CC));

ok $x->stringWithConditions         eq '<a><b/><c/></a>';

ok $x->stringWithConditions(qw(bb)) eq '<a><b/></a>';

ok $x->stringWithConditions(qw(cc)) eq '<a><c/></a>';

addConditions($@)

Add conditions to a node and return the node.

1  $node        Node
2  @conditions  Conditions to add.

Example:

$b->addConditions(qw(bb BB));

ok join(' ', $b->listConditions) eq 'BB bb';

deleteConditions($@)

Delete conditions applied to a node and return the node.

1  $node        Node
2  @conditions  Conditions to add.

Example:

ok join(' ', $b->listConditions) eq 'BB bb';

$b->deleteConditions(qw(BB));

ok join(' ', $b->listConditions) eq 'bb';

listConditions($)

Return a list of conditions applied to a node.

1  $node  Node.

Example:

$b->addConditions(qw(bb BB));

ok join(' ', $b->listConditions) eq 'BB bb';

Attributes

Get or set the attributes of nodes in the parse tree. Well known attributes can be set directly via lvalue subs for less well known attributes use attr.

class :lvalue

Attribute class for a node as an lvalue sub.

href :lvalue

Attribute href for a node as an lvalue sub.

id :lvalue

Attribute id for a node as an lvalue sub.

outputclass :lvalue

Attribute outputclass for a node as an lvalue sub.

attr :lvalue($$)

Return the value of an attribute of the current node as an lvalue sub.

1  $node       Node in parse tree
2  $attribute  Attribute name.

attrs($@)

Return the values of the specified attributes of the current node.

1  $node        Node in parse tree
2  @attributes  Attribute names.

Example:

ok -s $x eq '<a first="1" number="2" second="2"/>';

is_deeply [$x->attrs(qw(third second first ))], [undef, 2, 1];

attrCount($)

Return the number of attributes in the specified node.

1  $node  Node in parse tree

Example:

ok -s $x eq '<a first="1" number="2" second="2"/>';

ok $x->attrCount == 3;

getAttrs($)

Return a sorted list of all the attributes on this node.

1  $node  Node in parse tree.

Example:

ok -s $x eq '<a first="1" number="2" second="2"/>';

is_deeply [$x->getAttrs], [qw(first number second)];

setAttr($@)

Set the values of some attributes in a node and return the node.

1  $node    Node in parse tree
2  %values  (attribute name=>new value)*

Example:

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"/>';

deleteAttr($$$)

Delete the attribute, optionally checking its value first and return the node.

1  $node   Node
2  $attr   Attribute name
3  $value  Optional attribute value to check first.

Example:

ok -s $x eq '<a delete="me" number="2"/>';

$x->deleteAttr(qq(delete));

ok -s $x eq '<a number="2"/>';

deleteAttrs($@)

Delete any attributes mentioned in a list without checking their values and return the node.

1  $node   Node
2  @attrs  Attribute name

Example:

ok -s $x eq '<a first="1" number="2" second="2"/>';

$x->deleteAttrs(qw(first second third number));

ok -s $x eq '<a/>';

renameAttr($$$)

Change the name of an attribute regardless of whether the new attribute already exists and return the node.

1  $node  Node
2  $old   Existing attribute name
3  $new   New attribute name.

Example:

ok $x->printAttributes eq qq( no="1" word="first");

$x->renameAttr(qw(no number));

ok $x->printAttributes eq qq( number="1" word="first");

changeAttr($$$)

Change the name of an attribute unless it has already been set and return the node.

1  $node  Node
2  $old   Existing attribute name
3  $new   New attribute name.

Example:

ok $x->printAttributes eq qq( number="1" word="first");

$x->changeAttr(qw(number word));

ok $x->printAttributes eq qq( number="1" word="first");

renameAttrValue($$$$$)

Change the name and value of an attribute regardless of whether the new attribute already exists and return the node.

1  $node      Node
2  $old       Existing attribute name
3  $oldValue  Existing attribute value
4  $new       New attribute name
5  $newValue  New attribute value.

Example:

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");

changeAttrValue($$$$$)

Change the name and value of an attribute unless it has already been set and return the node.

1  $node      Node
2  $old       Existing attribute name
3  $oldValue  Existing attribute value
4  $new       New attribute name
5  $newValue  New attribute value.

Example:

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");

Traversal

Traverse the parse tree in various orders applying a sub to each node.

Post-order

This order allows you to edit children before their parents

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. The value of the current node is also made available via $_.

1  $node     Starting node
2  $sub      Sub to call for each sub node
3  @context  Accumulated context.

Example:

ok -p $x eq <<END;
<a>
  <b>
    <c id="42"/>
  </b>
  <d>
    <e/>
  </d>
</a>
END

my $s; $x->by(sub{$s .= $_->tag}); ok $s eq "cbeda"

byX($$@)

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 $_.

1  $node     Starting node
2  $sub      Sub to call
3  @context  Accumulated context.

Example:

ok -p $x eq <<END;
<a>
  <b>
    <c id="42"/>
  </b>
  <d>
    <e/>
  </d>
</a>
END

my $s; $x->byX(sub{$s .= $_->tag}); ok $s eq "cbeda"

byReverse($$@)

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 $_.

1  $node     Starting node
2  $sub      Sub to call for each sub node
3  @context  Accumulated context.

Example:

ok -p $x eq <<END;
<a>
  <b>
    <c id="42"/>
  </b>
  <d>
    <e/>
  </d>
</a>
END

my $s; $x->byReverse(sub{$s .= $_->tag}); ok $s eq "edcba"

byReverseX($$@)

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 $_.

1  $node     Starting node
2  $sub      Sub to call for each sub node
3  @context  Accumulated context.

Example:

ok -p $x eq <<END;
<a>
  <b>
    <c id="42"/>
  </b>
  <d>
    <e/>
  </d>
</a>
END

my $s; $x->byReverse(sub{$s .= $_->tag}); ok $s eq "edcba"

Pre-order

This order allows you to edit children after their parents

down($$@)

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 $_.

1  $node     Starting node
2  $sub      Sub to call for each sub node
3  @context  Accumulated context.

Example:

my $s; $x->down(sub{$s .= $_->tag}); ok $s eq "abcde"

downX($$@)

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 $_.

1  $node     Starting node
2  $sub      Sub to call for each sub node
3  @context  Accumulated context.

Example:

my $s; $x->down(sub{$s .= $_->tag}); ok $s eq "abcde"

downReverse($$@)

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 $_.

1  $node     Starting node
2  $sub      Sub to call for each sub node
3  @context  Accumulated context.

Example:

ok -p $x eq <<END;
<a>
  <b>
    <c id="42"/>
  </b>
  <d>
    <e/>
  </d>
</a>
END

my $s; $x->downReverse(sub{$s .= $_->tag}); ok $s eq "adebc"

downReverseX($$@)

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 $_.

1  $node     Starting node
2  $sub      Sub to call for each sub node
3  @context  Accumulated context.

Example:

ok -p $x eq <<END;
<a>
  <b>
    <c id="42"/>
  </b>
  <d>
    <e/>
  </d>
</a>
END

my $s; $x->downReverse(sub{$s .= $_->tag}); ok $s eq "adebc"

Pre and Post order

Visit the parent first, then the children, then the parent again.

through($$$@)

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 $_.

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.

Example:

my $s; my $n = sub{$s .= $_->tag}; $x->through($n, $n);

ok $s eq "abccbdeeda"

throughX($$$@)

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 $_.

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.

Example:

my $s; my $n = sub{$s .= $_->tag}; $x->through($n, $n);

ok $s eq "abccbdeeda"

Position

Confirm that the position navigated to is the expected position.

at($@)

Confirm that the node has the specified ancestry and return the starting node if it does else undef.

1  $start    Starting node
2  @context  Ancestry.

Example:

ok Data::Edit::Xml::new(<<END)->go(qw(b c -1 f))->at(qw(f c b a));
<a>
  <b>
    <c> <d/> </c>
    <c> <e/> </c>
    <c> <f/> </c>
  </b>
</a>
END

Use atX to execute at but die 'at' instead of returning undef

ancestry($)

Return a list containing: (the specified node, its parent, its parent's parent etc..)

1  $start  Starting node.

Example:

$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)];

context($)

Return a string containing the tag of the starting node and the tags of all its ancestors separated by single spaces.

1  $start  Starting node.

Example:

ok -p $x eq <<END;
<a>
  <b>
    <c id="42"/>
  </b>
  <d>
    <e/>
  </d>
</a>
END

ok $x->go(qw(d e))->context eq 'e d a';

containsSingleText($)

Return the singleton text element below this node else return undef

1  $node  Node.

Example:

if (1)

ok  $a->go(qw(b))->containsSingleText->text eq q(bb);

ok !$a->go(qw(c))->containsSingleText;

isFirst($)

Confirm that this node is the first node under its parent.

1  $node  Node.

Example:

ok -p $x eq <<END;
<a>
  <b>
    <c id="42"/>
  </b>
  <d>
    <e/>
  </d>
</a>
END

ok $x->go(qw(b))->isFirst;

Use isFirstX to execute isFirst but die 'isFirst' instead of returning undef

isLast($)

Confirm that this node is the last node under its parent.

1  $node  Node.

Example:

ok -p $x eq <<END;
<a>
  <b>
    <c id="42"/>
  </b>
  <d>
    <e/>
  </d>
</a>
END

ok $x->go(qw(d))->isLast;

Use isLastX to execute isLast but die 'isLast' instead of returning undef

isOnlyChild($@)

Return the specified node if it is the only node under its parent (and ancestors) ignoring any surrounding blank text.

1  $node  Node
2  @tags  Optional tags to confirm context.

Example:

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

isEmpty($)

Confirm that this node is empty, that is: this node has no content, not even a blank string of text.

1  $node  Node.

Example:

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

over($$)

Confirm that the string representing the tags at the level below this node match a regular expression.

1  $node  Node
2  $re    Regular expression.

Example:

my $x = Data::Edit::Xml::new(<<END);
<a>
  <b>
    <c/><d/><e/><f/><g/>
  </b>
</a>
END

ok $x->go(qw(b))->over(qr(d.+e));

Use overX to execute over but die 'over' instead of returning undef

matchAfter($$)

Confirm that the string representing the tags following this node matches a regular expression.

1  $node  Node
2  $re    Regular expression.

Example:

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

matchBefore($$)

Confirm that the string representing the tags preceding this node matches a regular expression

1  $node  Node
2  $re    Regular expression

Example:

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

path($)

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.

1  $node  Node.

Example:

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) == $_});

pathString($)

Return a string representing the path to a node

1  $node  Node.

Example:

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';

Navigation

Move around 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.

1  $node      Node
2  @position  Search specification.

Example:

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

c($$)

Return an array of all the nodes with the specified tag below the specified node.

1  $node  Node
2  $tag   Tag.

Example:

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)];

First

Find nodes that are first amongst their siblings.

first($)

Return the first node below this node.

1  $node  Node.

Use firstNonBlank to skip a (rare) initial blank text CDATA. Use firstNonBlankX to die rather then receive a returned undef or false result.

Example:

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))    ->first->id == 13;

Use firstX to execute first but die 'first' instead of returning undef

firstBy($@)

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.

1  $node  Node
2  @tags  Tags to search for.

Example:

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;

firstDown($@)

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.

1  $node  Node
2  @tags  Tags to search for.

Example:

my %f = $a->firstDown;

ok $f{b}->id == 15;

firstIn($@)

Return the first node matching one of the named tags under the specified node.

1  $node  Node
2  @tags  Tags to search for.

Example:

ok $a->prettyStringShowingCDATA 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

firstContextOf($@)

Return the first node encountered in the specified context in a depth first post-order traversal of the parse tree.

1  $node     Node
2  @context  Array of tags specifying context.

Example:

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

Last

Find nodes that are last amongst their siblings.

last($)

Return the last node below this node.

1  $node  Node.

Use lastNonBlank to skip a (rare) initial blank text CDATA. Use lastNonBlankX to die rather then receive a returned undef or false result.

Example:

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))    ->last ->id == 22;

Use lastX to execute last but die 'last' instead of returning undef

lastBy($@)

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.

1  $node  Node
2  @tags  Tags to search for.

Example:

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;

lastDown($@)

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.

1  $node  Node
2  @tags  Tags to search for.

Example:

my %l = $a->lastDown;

ok $l{b}->id == 26;

lastIn($@)

Return the first node matching one of the named tags under the specified node.

1  $node  Node
2  @tags  Tags to search for.

Example:

ok $a->prettyStringShowingCDATA 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

lastContextOf($@)

Return the last node encountered in the specified context in a depth first reverse pre-order traversal of the parse tree.

1  $node     Node
2  @context  Array of tags specifying context.

Example:

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

Next

Find sibling nodes after the specified node.

next($)

Return the node next to the specified node.

1  $node  Node.

Use nextNonBlank to skip a (rare) initial blank text CDATA. Use nextNonBlankX to die rather then receive a returned undef or false result.

Example:

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;

Use nextX to execute next but die 'next' instead of returning undef

nextIn($@)

Return the next node matching one of the named tags.

1  $node  Node
2  @tags  Tags to search for.

Example:

ok $a->prettyStringShowingCDATA 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

nextOn($@)

Step forwards as far as possible while remaining on nodes with the specified tags and return the last such node reached or the starting node if no such steps are possible.

1  $node  Start node
2  @tags  Tags identifying nodes that can be step on to context.

Example:

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 $c->nextOn(qw(d))  ->id == 2;

ok $c->nextOn(qw(c d))->id == 4;

ok $e->nextOn(qw(c d))     == $e;

Prev

Find sibling nodes before the specified node.

prev($)

Return the node previous to the specified node.

1  $node  Node.

Use prevNonBlank to skip a (rare) initial blank text CDATA. Use prevNonBlankX to die rather then receive a returned undef or false result.

Example:

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

Use prevX to execute prev but die 'prev' instead of returning undef

prevIn($@)

Return the next previous node matching one of the named tags.

1  $node  Node
2  @tags  Tags to search for.

Example:

ok $a->prettyStringShowingCDATA 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

prevOn($@)

Step backwards as far as possible while remaining on nodes with the specified tags and return the last such node reached or the starting node if no such steps are possible.

1  $node  Start node
2  @tags  Tags identifying nodes that can be step on to context.

Example:

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;

Upto

Methods for moving up the parse tree from a node.

upto($@)

Return the first ancestral node that matches the specified context.

1  $node  Start node
2  @tags  Tags identifying context.

Example:

$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

Editing

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 or by adding node as text

change($$@)

Change the name of a node, optionally confirming that the node is in a specified context and return the node.

1  $node  Node
2  $name  New name
3  @tags  Optional: tags defining the required context.

Example:

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

Cut and Put

Move nodes around in the parse tree by cutting and pasting them

cut($)

Cut out a node so that it can be reinserted else where in the parse tree.

1  $node  Node to cut out.

Example:

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

putFirst($$)

Place a cut out or new node at the front of the content of the specified node and return the new node.

1  $old  Original node
2  $new  New node.

Example:

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

putLast($$)

Place a cut out or new node last in the content of the specified node and return the new node.

1  $old  Original node
2  $new  New node.

Example:

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

putNext($$)

Place a cut out or new node just after the specified node and return the new node.

1  $old  Original node
2  $new  New node.

Example:

ok -p $a eq <<END;
<a id="aa">
  <b id="bb"/>
  <c id="cc"/>
</a>
END

$a->go(qw(c))->putNext($a->go(qw(b))->cut);

ok -p $a eq <<END;
<a id="aa">
  <c id="cc"/>
  <b id="bb"/>
</a>
END

putPrev($$)

Place a cut out or new node just before the specified node and return the new node.

1  $old  Original node
2  $new  New node.

Example:

ok -p $a eq <<END;
<a id="aa">
  <c id="cc"/>
  <b id="bb"/>
</a>
END

$a->go(qw(c))->putPrev($a->go(qw(b))->cut);

ok -p $a eq <<END;
<a id="aa">
  <b id="bb"/>
  <c id="cc"/>
</a>
END

Fusion

Join consecutive nodes

concatenate($$)

Concatenate two successive nodes and return the target node.

1  $target  Target node to replace
2  $source  Node to concatenate.

Example:

my $s = <<END;
<a>
  <b>
    <A/>
    <B/>
  </b>
  <c>
    <C/>
    <D/>
  </c>
</a>
END

my $a = Data::Edit::Xml::new($s);

$a->go(qw(b))->concatenate($a->go(qw(c)));

my $t = <<END;
<a>
  <b>
    <A/>
    <B/>
    <C/>
    <D/>
  </b>
</a>
END

ok $t eq -p $a;

concatenateSiblings($)

Concatenate preceding and following nodes as long as they have the same tag as the specified node and return the specified node.

1  $node  Concatenate around this node.

Example:

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

Put as text

Add text to the parse tree.

putFirstAsText($$)

Add a new text node first under a parent and return the new text node.

1  $node  The parent node
2  $text  The string to be added which might contain unparsed Xml as well as text.

Example:

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

putLastAsText($$)

Add a new text node last under a parent and return the new text node.

1  $node  The parent node
2  $text  The string to be added which might contain unparsed Xml as well as text.

Example:

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

putNextAsText($$)

Add a new text node following this node and return the new text node.

1  $node  The parent node
2  $text  The string to be added which might contain unparsed Xml as well as text.

Example:

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

putPrevAsText($$)

Add a new text node following this node and return the new text node

1  $node  The parent node
2  $text  The string to be added which might contain unparsed Xml as well as text

Example:

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 in and out

Break nodes out of nodes or push them back

breakIn($)

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.

1  $start  The start node.

Example:

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

breakInForwards($)

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.

1  $start  The start node.

Example:

ok -p $a eq <<END;
<a>
  <d/>
  <b>
    <c/>
    <c/>
  </b>
  <e/>
  <b>
    <c/>
    <c/>
  </b>
  <d/>
</a>
END

$a->go(qw(b))->breakInForwards;

ok -p $a eq <<END;
<a>
  <d/>
  <b>
    <c/>
    <c/>
    <e/>
    <c/>
    <c/>
    <d/>
  </b>
</a>
END

breakInBackwards($)

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.

1  $start  The start node.

Example:

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

breakOut($@)

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.

1  $parent  The parent node
2  @tags    The tags of the modes to be broken out.

Example:

my $A = Data::Edit::Xml::new("<a><b><d/><c/><c/><e/><c/><c/><d/></b></a>");

$a->go(qw(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

Replace nodes in the parse tree with nodes or text

replaceWith($$)

Replace a node (and all its content) with a new node (and all its content) and return the new node.

1  $old  Old node
2  $new  New node.

Example:

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>';

replaceWithText($$)

Replace a node (and all its content) with a new text node and return the new node.

1  $old   Old node
2  $text  Text of new node.

Example:

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>';

replaceWithBlank($)

Replace a node (and all its content) with a new blank text node and return the new node.

1  $old  Old node

Example:

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>';

Wrap and unwrap

Wrap and unwrap nodes to alter the depth of the parse tree

wrapWith($$@)

Wrap the original node in a new node forcing the original node down deepening the parse tree; return the new wrapping node.

1  $old         Node
2  $tag         Tag for the L<new node|/newTag>
3  %attributes  Attributes for the L<new node|/newTag>.

Example:

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

wrapUp($@)

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.

1  $node  Node to wrap
2  @tags  Tags to wrap the node with - with the uppermost tag rightmost.

Example:

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

wrapDown($@)

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.

1  $node  Node to wrap
2  @tags  Tags to wrap the node with - with the uppermost tag rightmost.

Example:

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

wrapContentWith($$@)

Wrap the content of a node in a new node, the original content then contains the new node which contains the original node's content; returns the new wrapped node.

1  $old         Node
2  $tag         Tag for new node
3  %attributes  Attributes for new node.

Example:

ok -p $x eq <<END;
<a>
  <b>
    <c/>
    <c/>
    <c/>
  </b>
</a>
END

$x->go(qw(b))->wrapContentWith(qw(D id DD));

ok -p $x eq <<END;
<a>
  <b>
    <D id="DD">
      <c/>
      <c/>
      <c/>
    </D>
  </b>
</a>
END

wrapTo($$$@)

Wrap all the nodes starting and ending at the specified nodes 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.

1  $start       Start node
2  $end         End node
3  $tag         Tag for the wrapping node
4  %attributes  Attributes for the wrapping node

Example:

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

Use wrapToX to execute wrapTo but die 'wrapTo' instead of returning undef

unwrap($)

Unwrap a node by inserting its content into its parent at the point containing the node and return the parent node.

1  $node  Node to unwrap.

Example:

ok -s $x eq "<a>A<b> c </b>B</a>";

$b->unwrap;

ok -s $x eq "<a>A c B</a>";

Contents

The children of each node.

contents($)

Return all the nodes contained by this node either as an array or as a reference to such an array.

1  $node  Node.

Example:

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)];

contentAfter($)

Return all the sibling following this node.

1  $node  Node.

Example:

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;

contentBefore($)

Return all the sibling preceding this node.

1  $node  Node.

Example:

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;

contentAsTags($)

Return a string containing the tags of all the nodes contained by this node separated by single spaces.

1  $node  Node.

Example:

my $x = Data::Edit::Xml::new(<<END);
<a>
  <b>
    <c/><d/><e/><f/><g/>
  </b>
</a>
END

ok $x->go(qw(b))->contentAsTags eq 'c d e f g';

contentAfterAsTags($)

Return a string containing the tags of all the sibling nodes following this node separated by single spaces.

1  $node  Node.

Example:

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';

contentBeforeAsTags($)

# Return a string containing the tags of all the sibling nodes preceding this node separated by single spaces.

1  $node  Node.

Example:

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';

position($)

Return the index of a node in its parent's content.

1  $node  Node.

Example:

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;

index($)

Return the index of a node in its parent index.

1  $node  Node.

Example:

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;

present($@)

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.

1  $node   Node
2  @names  Possible tags immediately under the node.

Example:

is_deeply {$a->first->present}, {c=>2, d=>2, e=>1};

isText($)

Confirm that this is a text node.

1  $node  Node to test.

Example:

ok $a->prettyStringShowingCDATA eq <<END;
<a><CDATA> </CDATA>
</a>
END

ok $a->first->isText;

Use isTextX to execute isText but die 'isText' instead of returning undef

isBlankText($)

Confirm that this is a text node and that it is blank.

1  $node  Node to test.

Example:

ok $a->prettyStringShowingCDATA eq <<END;
<a><CDATA> </CDATA>
</a>
END

ok $a->first->isBlankText;

Use isBlankTextX to execute isBlankText but die 'isBlankText' instead of returning undef

Order

Number and verify the order of nodes.

findByNumber($$)

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.

1  $node    Node in the parse tree to search
2  $number  Number of the node required.

Example:

$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

findByNumbers($@)

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.

1  $node     Node in the parse tree to search
2  @numbers  Numbers of the nodes required.

Example:

$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)];

numberTree($)

Number the parse tree

1  $node  Node

Example:

$x->numberTree;

ok -z $x eq <<END;
<a id="1">
  <b id="2">
    <c id="3" id="42"/>
  </b>
  <d id="4">
    <e id="5"/>
  </d>
</a>
END

above($$)

Return the specified node if it is above the specified target otherwise undef

1  $node    Node
2  $target  Target.

Example:

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

below($$)

Return the specified node if it is below the specified target otherwise undef

1  $node    Node
2  $target  Target.

Example:

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

after($$)

Return the specified node if it occurs after the target node in the parse tree or else undef if the node is above, below or before the target.

1  $node    Node
2  $target  Targe.t

Example:

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

before($$)

Return the specified node if it occurs before the target node in the parse tree or else undef if the node is above, below or after the target.

1  $node    Node
2  $target  Target.

Example:

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

disordered($@)

Return the first node that is out of the specified order when performing a pre-ordered traversal of the parse tree.

1  $node   Node
2  @nodes  Following nodes.

Example:

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);

ordered($@)

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

1  $node   Node
2  @nodes  Following nodes.

Example:

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

Labels

Label nodes so that they can be cross referenced and linked by Data::Edit::Xml::Lint

addLabels($@)

Add the named labels to the specified node and return that node.

1  $node    Node in parse tree
2  @labels  Names of labels to add.

Example:

ok -r $x eq '<a><b><c/></b></a>';

ok $b->countLabels == 0;

$b->addLabels(1..2);

$b->addLabels(3..4);

ok -r $x eq '<a><b id="1, 2, 3, 4"><c/></b></a>';

countLabels($)

Return the count of the number of labels at a node.

1  $node  Node in parse tree.

Example:

ok -r $x eq '<a><b><c/></b></a>';

ok $b->countLabels == 0;

$b->addLabels(1..2);

$b->addLabels(3..4);

ok -r $x eq '<a><b id="1, 2, 3, 4"><c/></b></a>';

ok $b->countLabels == 4;

getLabels($)

Return the names of all the labels set on a node.

1  $node  Node in parse tree.

Example:

ok -r $x eq '<a><b><c/></b></a>';

ok $b->countLabels == 0;

$b->addLabels(1..2);

$b->addLabels(3..4);

ok -r $x eq '<a><b id="1, 2, 3, 4"><c/></b></a>';

is_deeply [1..4], [$b->getLabels];

deleteLabels($@)

Delete the specified labels in the specified node or all labels if no labels have are specified and return that node.

1  $node    Node in parse tree
2  @labels  Names of the labels to be deleted

Example:

ok -r $x eq '<a><b id="1, 2, 3, 4"><c id="1, 2, 3, 4"/></b></a>';

$b->deleteLabels(1,4) for 1..2;

ok -r $x eq '<a><b id="2, 3"><c id="1, 2, 3, 4"/></b></a>';

copyLabels($$)

Copy all the labels from the source node to the target node and return the source node.

1  $source  Source node
2  $target  Target node.

Example:

ok -r $x eq '<a><b id="1, 2, 3, 4"><c/></b></a>';

$b->copyLabels($c) for 1..2;

ok -r $x eq '<a><b id="1, 2, 3, 4"><c id="1, 2, 3, 4"/></b></a>';

moveLabels($$)

Move all the labels from the source node to the target node and return the source node.

1  $source  Source node
2  $target  Target node.

Example:

ok -r $x eq '<a><b id="2, 3"><c id="1, 2, 3, 4"/></b></a>';

$b->moveLabels($c) for 1..2;

ok -r $x eq '<a><b><c id="1, 2, 3, 4"/></b></a>';

Operators

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.

opString($$)

-b: previous node

-c: next node

-e: prettyStringEnd

-f: first node

-l: last node

-o: stringQuoted

-p: prettyString

-r: stringReplacingIdWithLabels

-s: string

-S : stringNode

-t : tag

-u: id

-z: prettyStringNumbered.

1  $node  Node
2  $op    Monadic operator.

Example:

my $x = Data::Edit::Xml::new(<<END);
<a>
  <b>
    <c id="42"/>
  </b>
  <d>
    <e/>
  </d>
</a>
END

my $prev = -b $x->go(q(d));

ok -t $prev eq q(b);

my $next = -c $x->go(q(b));

ok -t $next eq q(d);

my $first = -f $x;

ok -t $first eq q(b);

my $last  = -l $x;

ok -t $last eq q(d);

ok -o $x eq "'<a><b><c id=\"42\"/></b><d><e/></d></a>'";

ok -p $x eq <<END;
<a>
  <b>
    <c id="42"/>
  </b>
  <d>
    <e/>
  </d>
</a>
END

ok -s $x eq '<a><b><c id="42"/></b><d><e/></d></a>';

ok -t $x eq 'a';

$x->numberTree;

ok -z $x eq <<END;
<a id="1">
  <b id="2">
    <c id="3" id="42"/>
  </b>
  <d id="4">
    <e id="5"/>
  </d>
</a>
END

Statistics

Statistics describing the parse tree.

count($@)

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.

1  $node   Node
2  @names  Possible tags immediately under the node.

Example:

my $x = Data::Edit::Xml::new(<<END);
<a>

</a>
END

ok $x->count == 0;

countTags($)

Count the number of tags in a parse tree.

1  $node  Parse tree.

Example:

ok -p $a eq <<END;
<a id="aa">
  <b id="bb">
    <c id="cc"/>
  </b>
</a>
END

ok $a->countTags == 3;

countTagNames($$)

Return a hash showing the number of instances of each tag on and below the specified node.

1  $node   Node
2  $count  Count of tags so far.

Example:

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 };

countAttrNames($$)

Return a hash showing the number of instances of each attribute on and below the specified node.

1  $node   Node
2  $count  Count of attributes so far.

Example:

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 };

Debug

Debugging methods

Private Methods

tree($$)

Build a tree representation of the parsed xml which can be easily traversed to look for things.

1  $parent  The parent node
2  $parse   The remaining parse

disconnectLeafNode($)

Remove a leaf node from the parse tree and make it into its own parse tree.

1  $node  Leaf node to disconnect.

indexNode($)

Index the children of a node so that we can access them by tag and number.

1  $node  Node to index.

prettyStringEnd($)

Return a readable string representing a node of a parse tree and all the nodes below it as a here document

1  $node  Start node

numberNode($)

Ensure that this node has a number.

1  $node  Node

printAttributes($)

Print the attributes of a node.

1  $node  Node whose attributes are to be printed.

Example:

my $x = Data::Edit::Xml::new(my $s = <<END);
<a no="1" word="first"/>
END

ok $x->printAttributes eq qq( no="1" word="first");

printAttributesReplacingIdsWithLabels($)

Print the attributes of a node replacing the id with the labels.

1  $node  Node whose attributes are to be printed.

checkParentage($)

Check the parent pointers are correct in a parse tree.

1  $x  Parse tree.

checkParser($)

Check that every node has a parser.

1  $x  Parse tree.

nn($)

Replace new lines in a string with N to make testing easier.

1  $s  String.

Index

above

aboveX

addConditions

addLabels

after

afterX

ancestry

at

attr :lvalue

attrCount

attributes

attrs

atX

before

beforeX

below

belowX

breakIn

breakInBackwards

breakInForwards

breakOut

by

byReverse

byReverseX

byX

c

cdata

change

changeAttr

changeAttrValue

changeX

checkParentage

checkParser

class

clone

concatenate

concatenateSiblings

conditions

containsSingleText

content

contentAfter

contentAfterAsTags

contentAsTags

contentBefore

contentBeforeAsTags

contents

context

copyLabels

count

countAttrNames

countLabels

countTagNames

countTags

cut

deleteAttr

deleteAttrs

deleteConditions

deleteLabels

disconnectLeafNode

disordered

down

downReverse

downReverseX

downX

equals

equalsX

errorsFile

findByNumber

findByNumbers

findByNumberX

first

firstBy

firstContextOf

firstContextOfX

firstDown

firstIn

firstInX

firstNonBlank

firstNonBlankX

firstX

getAttrs

getLabels

go

goX

href

id

index

indexes

indexNode

input

inputFile

inputString

isBlankText

isBlankTextX

isEmpty

isEmptyX

isFirst

isFirstX

isLast

isLastX

isOnlyChild

isOnlyChildX

isText

isTextX

labels

last

lastBy

lastContextOf

lastContextOfX

lastDown

lastIn

lastInX

lastNonBlank

lastNonBlankX

lastX

listConditions

matchAfter

matchAfterX

matchBefore

matchBeforeX

moveLabels

new

newTag

newText

newTree

next

nextIn

nextInX

nextNonBlank

nextNonBlankX

nextOn

nextX

nn

number

numbering

numberNode

numbers

numberTree

opString

ordered

orderedX

outputclass

over

overX

parent

parse

parser

path

pathString

position

present

PrettyContentString

prettyString

prettyStringEnd

prettyStringNumbered

prettyStringShowingCDATA

prev

prevIn

prevInX

prevNonBlank

prevNonBlankX

prevOn

prevX

printAttributes

printAttributesReplacingIdsWithLabels

putFirst

putFirstAsText

putLast

putLastAsText

putNext

putNextAsText

putPrev

putPrevAsText

renameAttr

renameAttrValue

renew

replaceSpecialChars

replaceWith

replaceWithBlank

replaceWithText

restore

restoreX

save

setAttr

string

stringContent

stringNode

stringQuoted

stringReplacingIdsWithLabels

stringWithConditions

tag

text

through

throughX

tree

unwrap

upto

uptoX

wrapContentWith

wrapDown

wrapTo

wrapToX

wrapUp

wrapWith

Installation

This module is written in 100% Pure Perl and, thus, it is easy to read, use, modify and install.

Standard Module::Build process for building and installing modules:

perl Build.PL
./Build
./Build test
./Build install

Author

philiprbrenan@gmail.com

http://www.appaapps.com

Copyright

Copyright (c) 2016-2017 Philip R Brenan.

This module is free software. It may be used, redistributed and/or modified under the same terms as Perl itself.