The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

Name

Data::Edit::Xml - Edit data held in the 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(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)))                                                          # <p>
     {if (my $t = $_->containsSingleText)                                       # <p> with single text
       {if ($t->text =~ s(\A\x{2022}\s*) ()s)                                   # Starting with a bullet
         {$_->change(qw(li));                                                   # <p> to <li>
          if (my $p = $_->prev(qw(ul)))                                         # Previous element is ul?
           {$p->putLast($_->cut);                                               # Put in preceding list or create a new list
           }
          else
           {$_->wrapWith(qw(ul))
           }
         }
       }
     }
   });

To get:

  <a>
    <ul>
      <li>Minimum 1 number</li>
      <li>No leading, trailing, or embedded spaces</li>
      <li>Not case-sensitive</li>
    </ul>
  </a>

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

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.

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

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

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

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

     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.  

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.

     Parameter  Description           
  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, 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 add them to the parse tree. Returns the starting node of the new parse tree or undef if the optional context constraint was not 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.

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 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. Returns the starting node of the new parse tree or undef if the optional context constraint was not supplied but not satisfied.

     Parameter  Description         
  1  $node      Node to clone 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.

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.

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

     Parameter  Description  
  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".

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

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

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

prettyStringCDATA($$)

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

     Parameter  Description      
  1  $node      Start node       
  2  $depth     Optional depth.  

Example:

  if (1)
  
  $a->first->replaceWithBlank;
  
  ok $a->prettyStringCDATA 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->prettyStringCDATA eq <<'END';
  <a><CDATA> </CDATA>
      <A/>
  <CDATA>  </CDATA>
      <C/>
  <CDATA>  </CDATA>
      <E/>
  <CDATA>  </CDATA>
      <G/>
  <CDATA>  </CDATA>
  </a>
  END
  

prettyStringContent($)

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

     Parameter  Description  
  1  $node      Start node.  

Example:

  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
  

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

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

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

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

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

     Parameter  Description  
  1  $node      Node.        

Example:

  ok -r $x eq '<a><b><c/></b></a>';
  
  my $b = $x->go(q(b));
  
  $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.

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

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

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

     Parameter  Description  
  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. To set or get the values of other attributes use Get or Set Attributes. To delete or rename attributes see: Other Operations on Attributes.

Well Known Attributes

Get or set these attributes of nodes via lvalue subs as in:

  $x->href = "#ref";

class :lvalue

Attribute class for a node as an lvalue sub.

guid :lvalue

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

Attribute navtitle for a node as an lvalue sub.

otherprops :lvalue

Attribute otherprops for a node as an lvalue sub.

outputclass :lvalue

Attribute outputclass for a node as an lvalue sub.

props :lvalue

Attribute props for a node as an lvalue sub.

style :lvalue

Attribute style for a node as an lvalue sub.

type :lvalue

Attribute type for a node as an lvalue sub.

Get or Set Attributes

Get or set the attributes of nodes.

attr :lvalue($$)

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

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

setAttr($@)

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

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

Other Operations on Attributes

Perform operations other than get or set on the attributes of a node

attrs($@)

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

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

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

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

deleteAttr($$$)

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

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

     Parameter  Description                
  1  $node      Node                       
  2  @attrs     Attribute names to delete  

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.

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

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

     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.      

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.

     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.      

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

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

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

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

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

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

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

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

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

     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.             

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

     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.             

Example:

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

Range

Ranges of nodes

from($@)

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  

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

to($@)

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  

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

fromTo($$@)

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  

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

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

     Parameter  Description    
  1  $start     Starting node  
  2  @context   Ancestry.      

Example:

  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, qq(c), undef, qq(a));
  
  ok  $a->go(qw(b c  d))  ->at(qw(d c b),    undef);
  
  ok !$a->go(qw(b c  d))  ->at(qw(d c b),    undef, undef);
  
  ok !$a->go(qw(b c  d))  ->at(qw(d e b));
  

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

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

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

     Parameter  Description  
  1  $node      Node.        

Example:

  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;
  

depth($)

Returns the depth of the specified node, the depth of a root node is zero.

     Parameter  Description  
  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 0 == $a->depth;
  
  ok 4 == $a->findByNumber(14)->depth;
  

isFirst($@)

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

Example:

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

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

isLast($@)

Return the specified node if it is last under its parent and optionally has the specified context, else return undef

     Parameter  Description       
  1  $node      Node              
  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.

Example:

  ok -p $x eq <<END;
  <a>
    <b>
      <c id="42"/>
    </b>
    <d>
      <e/>
    </d>
  </a>
  END
  
  ok $x->go(q(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.

     Parameter  Description       
  1  $node      Node              
  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.

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.

     Parameter  Description       
  1  $node      Node              
  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.

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.

     Parameter  Description         
  1  $node      Node                
  2  $re        Regular expression  
  3  @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.

Example:

  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

matchAfter($$@)

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

     Parameter  Description         
  1  $node      Node                
  2  $re        Regular expression  
  3  @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.

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

     Parameter  Description         
  1  $node      Node                
  2  $re        Regular expression  
  3  @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.

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.

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

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

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

     Parameter  Description  
  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 optionally checking its context.

     Parameter  Description        
  1  $node      Node               
  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.

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

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.

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

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

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

Example:

  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

firstInIndex($@)

Return the specified node if it is first in its index and optionally at the specified context else undef

     Parameter  Description        
  1  $node      Node               
  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.

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 (5)->firstInIndex;
  
  ok !$a->findByNumber(7) ->firstInIndex;
  

Use firstInIndexX to execute firstInIndex but die 'firstInIndex' 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.

     Parameter  Description                        
  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 optionally checking its context.

     Parameter  Description        
  1  $node      Node               
  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.

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

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.

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

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

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

Example:

  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

lastInIndex($@)

Return the specified node if it is last in its index and optionally at the specified context else undef

     Parameter  Description        
  1  $node      Node               
  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.

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(10)->lastInIndex;
  
  ok !$a->findByNumber(7) ->lastInIndex;
  

Use lastInIndexX to execute lastInIndex but die 'lastInIndex' 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.

     Parameter  Description                        
  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, optionally checking its context.

     Parameter  Description        
  1  $node      Node               
  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.

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

nextIn($@)

Return the next node matching one of the named tags.

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

Example:

  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

nextOn($@)

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.  

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 before the specified node, optionally checking its context.

     Parameter  Description        
  1  $node      Node               
  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.

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

prevIn($@)

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

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

Example:

  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

prevOn($@)

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.

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

     Parameter  Description                
  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 new text nodes.

change($$@)

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

     Parameter  Description                                    
  1  $node      Node                                           
  2  $name      New name                                       
  3  @tags      Optional: tags defining the required 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.

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.

     Parameter  Description       
  1  $node      Node to cut out   
  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.

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.

     Parameter  Description        
  1  $old       Original node      
  2  $new       New node           
  3  @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.

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.

     Parameter  Description        
  1  $old       Original node      
  2  $new       New node           
  3  @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.

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.

     Parameter  Description        
  1  $old       Original node      
  2  $new       New node           
  3  @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.

Example:

  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
  

putPrev($$@)

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

     Parameter  Description        
  1  $old       Original node      
  2  $new       New node           
  3  @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.

Example:

  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
  

Fusion

Join consecutive nodes

concatenate($$@)

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  

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.

Example:

  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;
  

concatenateSiblings($@)

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.             

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.

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.

     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.                                                        

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.

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.

     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.                                                        

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.

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.

     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.                                                        

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.

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

     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.                                                        

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.

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.

     Parameter  Description        
  1  $start     The start node     
  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.

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.

     Parameter  Description         
  1  $start     The start node      
  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.

Example:

  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
  

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.

     Parameter  Description         
  1  $start     The start node      
  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.

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.

     Parameter  Description                              
  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(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

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.

     Parameter  Description         
  1  $old       Old node            
  2  $new       New node            
  3  @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.

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.

     Parameter  Description        
  1  $old       Old node           
  2  $text      Text of new node   
  3  @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.

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.

     Parameter  Description        
  1  $old       Old node           
  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.

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.

     Parameter    Description                          
  1  $old         Node                                 
  2  $tag         Tag for the new node or tag          
  3  %attributes  Attributes for the new node or tag.  

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.

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

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

Example:

  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
  

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

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.

     Parameter  Description        
  1  $node      Node to unwrap     
  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.

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

     Parameter  Description        
  1  $node      Node               
  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 an empty list () immediately.

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

     Parameter  Description        
  1  $node      Node               
  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 an empty list () immediately.

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

     Parameter  Description        
  1  $node      Node               
  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 an empty list () immediately.

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 or the empty string if the node is empty or does not match the optional context

     Parameter  Description        
  1  $node      Node               
  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 an empty list () immediately.

Example:

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

contentAfterAsTags($@)

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 does not match the optional context.

     Parameter  Description        
  1  $node      Node               
  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 an empty list () immediately.

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 or the empty string if the node is empty or does not match the optional context.

     Parameter  Description        
  1  $node      Node               
  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 an empty list () immediately.

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.

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

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

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

Example:

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

isText($@)

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  

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.

Example:

  ok $a->prettyStringCDATA eq <<END;
  <a><CDATA> </CDATA></a>
  END
  
  ok $a->first->isText;
  

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

isBlankText($@)

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

     Parameter  Description       
  1  $node      Node to test      
  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.

Example:

  ok $a->prettyStringCDATA eq <<END;
  <a><CDATA> </CDATA></a>
  END
  
  ok $a->first->isBlankText;
  

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

isAllBlankText($@)

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

     Parameter  Description       
  1  $node      Node to test      
  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.

Example:

  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

bitsNodeTextBlank($)

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.  

Example:

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

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.

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

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

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

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

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

     Parameter  Description  
  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 $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.

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

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

commonAncestor($@)

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       

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

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

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

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

Example:

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

     Parameter  Description          
  1  $node      Node in parse tree.  

Example:

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

     Parameter  Description          
  1  $node      Node in parse tree.  

Example:

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

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

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

     Parameter  Description   
  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: bitsNodeTextBlank

-b: previous node

-c: next node

-e: prettyStringEnd

-f: first node

-l: last node

-M: number

-o: stringQuoted

-p: prettyString

-r: stringReplacingIdsWithLabels

-s: string

-S : stringNode

-t : tag

-u: id

-z: prettyStringNumbered.

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

opContents($)

@{} : content of a node.

     Parameter  Description  
  1  $node      Node.        

Example:

  ok -p $x eq <<END;
  <a>
    <b>
      <c id="42"/>
    </b>
    <d>
      <e/>
    </d>
  </a>
  END
  
  ok 'bd' eq join '', map {$_->tag} @$x ;
  

opAt($$)

<= : Check that a node is in the context specified by the referenced array of words.

     Parameter  Description                                                              
  1  $node      Node                                                                     
  2  $context   Reference to array of words specifying the parents of the desired node.  

Example:

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

opNew($$)

** : create a new node from the text on the right hand side: if the text contains a non word character \W the node will be create as text, else it will be created as a tag

     Parameter  Description                                              
  1  $node      Node                                                     
  2  $text      Name node of node to create or text of new text element  

Example:

  my $a = Data::Edit::Xml::new("<a/>");
  
  my $b = $a ** q(b);
  
  ok -s $b eq "<b/>";
  

opPutFirst($$)

>> : put a node or string first under a node and return the new node.

     Parameter  Description                                  
  1  $node      Node                                         
  2  $text      Node or text to place first under the node.  

Example:

  ok -p $a eq <<END;
  <a/>
  END
  
  my $f = $a >> qq(first);
  
  ok -p $a eq <<END;
  <a>
    <first/>
  </a>
  END
  

opPutFirstAssign($$)

>>= : put a node or string first under a node.

     Parameter  Description                                  
  1  $node      Node                                         
  2  $text      Node or text to place first under the node.  

Example:

  ok -p $a eq <<END;
  <a/>
  END
  
  $a >>= qq(first);
  
  ok -p $a eq <<END;
  <a>
    <first/>
  </a>
  END
  

opPutLast($$)

<< : put a node or string last under a node and return the new node.

     Parameter  Description                                 
  1  $node      Node                                        
  2  $text      Node or text to place last under the node.  

Example:

  ok -p $a eq <<END;
  <a>
    <first/>
  </a>
  END
  
  my $l = $a << qq(last);
  
  ok -p $a eq <<END;
  <a>
    <first/>
    <last/>
  </a>
  END
  

opPutLastAssign($$)

<<= : put a node or string last under a node.

     Parameter  Description                                 
  1  $node      Node                                        
  2  $text      Node or text to place last under the node.  

Example:

  ok -p $a eq <<END;
  <a>
    <first/>
  </a>
  END
  
  $a <<= qq(last);
  
  ok -p $a eq <<END;
  <a>
    <first/>
    <last/>
  </a>
  END
  

opPutNext($$)

> + : put a node or string after the specified node and return the new node.

     Parameter  Description                                  
  1  $node      Node                                         
  2  $text      Node or text to place after the first node.  

Example:

  ok -p $a eq <<END;
  <a>
    <first/>
    <last/>
  </a>
  END
  
  $f += qq(next);
  
  ok -p $a eq <<END;
  <a>
    <first/>
    <next/>
    <last/>
  </a>
  END
  

opPutNextAssign($$)

+= : put a node or string after the specified node.

     Parameter  Description                                  
  1  $node      Node                                         
  2  $text      Node or text to place after the first node.  

Example:

  ok -p $a eq <<END;
  <a>
    <first/>
    <last/>
  </a>
  END
  
  my $f = -f $a;
  
  $f += qq(next);
  
  ok -p $a eq <<END;
  <a>
    <first/>
    <next/>
    <last/>
  </a>
  END
  

opPutPrev($$)

< - : put a node or string before the specified node and return the new node.

     Parameter  Description                                   
  1  $node      Node                                          
  2  $text      Node or text to place before the first node.  

Example:

  ok -p $a eq <<END;
  <a>
    <first/>
    <next/>
    <last/>
  </a>
  END
  
  $l -= qq(prev);
  
  ok -p $a eq <<END;
  <a>
    <first/>
    <next/>
    <prev/>
    <last/>
  </a>
  END
  

opPutPrevAssign($$)

-= : put a node or string before the specified node,

     Parameter  Description                                   
  1  $node      Node                                          
  2  $text      Node or text to place before the first node.  

Example:

  ok -p $a eq <<END;
  <a>
    <first/>
    <next/>
    <last/>
  </a>
  END
  
  my $l = -l $a;
  
  $l -= qq(prev);
  
  ok -p $a eq <<END;
  <a>
    <first/>
    <next/>
    <prev/>
    <last/>
  </a>
  END
  

opBy($$)

x= : Traverse a parse tree in post-order.

     Parameter  Description                         
  1  $node      Parse tree                          
  2  $code      Code to execute against each node.  

Example:

  ok -p $x eq <<END;
  <a>
    <b>
      <c id="42"/>
    </b>
    <d>
      <e/>
    </d>
  </a>
  END
  
  my $s; $x x= sub{$s .= -t $_}; ok $s eq "cbeda"
  

opGo($$)

>= : Search for a node via a specification provided as a reference to an array of words each number. Each word represents a tag name, each number the index of the previous tag or zero by default.

     Parameter  Description                                  
  1  $node      Node                                         
  2  $go        Reference to an array of search parameters.  

Example:

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

opAttr($$)

% : Get the value of an attribute of this node.

     Parameter  Description                                                                    
  1  $node      Node                                                                           
  2  $attr      Reference to an array of words and numbers specifying the node to search for.  

Example:

  my $a = Data::Edit::Xml::new('<a number="1"/>');
  
  ok $a %  qq(number) == 1;
  

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.

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

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

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

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

countAttrValues($$)

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

     Parameter  Description                  
  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->countAttrValues, { A => 1, B => 2, C => 4 };
  

countOutputClasses($$)

Count instances of outputclass attributes

     Parameter  Description    
  1  $node      Node           
  2  $count     Count so far.  

Example:

  my $a = Data::Edit::Xml::newTree("a", id=>1, class=>2, href=>3, outputclass=>4);
  
  is_deeply { 4 => 1 }, $a->countOutputClasses;
  

Debug

Debugging methods

Private Methods

tree($$)

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  

disconnectLeafNode($)

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

     Parameter  Description               
  1  $node      Leaf node to disconnect.  

reindexNode($)

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

     Parameter  Description     
  1  $node      Node to index.  

indexNode($)

Merge multiple text segments and set parent and parser after changes to a node

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

     Parameter  Description  
  1  $node      Start node   

numberNode($)

Ensure that this node has a number.

     Parameter  Description  
  1  $node      Node         

printAttributes($)

Print the attributes of a node.

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

     Parameter  Description                               
  1  $node      Node whose attributes are to be printed.  

checkParentage($)

Check the parent pointers are correct in a parse tree.

     Parameter  Description  
  1  $x         Parse tree.  

checkParser($)

Check that every node has a parser.

     Parameter  Description  
  1  $x         Parse tree.  

nn($)

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

     Parameter  Description  
  1  $s         String.      

Index

1 above

2 aboveX

3 addConditions

4 addLabels

5 after

6 afterX

7 ancestry

8 at

9 attr :lvalue

10 attrCount

11 attributes

12 attrs

13 atX

14 before

15 beforeX

16 below

17 belowX

18 bitsNodeTextBlank

19 breakIn

20 breakInBackwards

21 breakInBackwardsNonBlank

22 breakInBackwardsNonBlankX

23 breakInForwards

24 breakInForwardsNonBlank

25 breakInForwardsNonBlankX

26 breakInNonBlank

27 breakInNonBlankX

28 breakOut

29 by

30 byReverse

31 byReverseX

32 byX

33 c

34 cdata

35 change

36 changeAttr

37 changeAttrValue

38 changeNonBlank

39 changeNonBlankX

40 changeX

41 checkParentage

42 checkParser

43 class

44 clone

45 cloneNonBlank

46 cloneNonBlankX

47 commonAncestor

48 commonAncestorX

49 concatenate

50 concatenateNonBlank

51 concatenateNonBlankX

52 concatenateSiblings

53 concatenateSiblingsNonBlank

54 concatenateSiblingsNonBlankX

55 conditions

56 containsSingleText

57 content

58 contentAfter

59 contentAfterAsTags

60 contentAfterAsTagsNonBlank

61 contentAfterAsTagsNonBlankX

62 contentAfterNonBlank

63 contentAfterNonBlankX

64 contentAsTags

65 contentAsTagsNonBlank

66 contentAsTagsNonBlankX

67 contentBefore

68 contentBeforeAsTags

69 contentBeforeAsTagsNonBlank

70 contentBeforeAsTagsNonBlankX

71 contentBeforeNonBlank

72 contentBeforeNonBlankX

73 contents

74 contentsNonBlank

75 contentsNonBlankX

76 context

77 copyLabels

78 count

79 countAttrNames

80 countAttrValues

81 countLabels

82 countOutputClasses

83 countTagNames

84 countTags

85 cut

86 cutNonBlank

87 cutNonBlankX

88 deleteAttr

89 deleteAttrs

90 deleteConditions

91 deleteLabels

92 depth

93 disconnectLeafNode

94 disordered

95 down

96 downReverse

97 downReverseX

98 downX

99 equals

100 equalsX

101 errorsFile

102 findByNumber

103 findByNumbers

104 findByNumberX

105 first

106 firstBy

107 firstContextOf

108 firstContextOfX

109 firstDown

110 firstIn

111 firstInIndex

112 firstInIndexNonBlank

113 firstInIndexNonBlankX

114 firstInIndexX

115 firstInX

116 firstNonBlank

117 firstNonBlankX

118 firstX

119 from

120 fromTo

121 getAttrs

122 getLabels

123 go

124 goX

125 guid

126 href

127 id

128 index

129 indexes

130 indexNode

131 input

132 inputFile

133 inputString

134 isAllBlankText

135 isAllBlankTextNonBlank

136 isAllBlankTextNonBlankX

137 isAllBlankTextX

138 isBlankText

139 isBlankTextNonBlank

140 isBlankTextNonBlankX

141 isBlankTextX

142 isEmpty

143 isEmptyNonBlank

144 isEmptyNonBlankX

145 isEmptyX

146 isFirst

147 isFirstNonBlank

148 isFirstNonBlankX

149 isFirstX

150 isLast

151 isLastNonBlank

152 isLastNonBlankX

153 isLastX

154 isOnlyChild

155 isOnlyChildNonBlank

156 isOnlyChildNonBlankX

157 isOnlyChildX

158 isText

159 isTextNonBlank

160 isTextNonBlankX

161 isTextX

162 labels

163 last

164 lastBy

165 lastContextOf

166 lastContextOfX

167 lastDown

168 lastIn

169 lastInIndex

170 lastInIndexNonBlank

171 lastInIndexNonBlankX

172 lastInIndexX

173 lastInX

174 lastNonBlank

175 lastNonBlankX

176 lastX

177 listConditions

178 matchAfter

179 matchAfterNonBlank

180 matchAfterNonBlankX

181 matchAfterX

182 matchBefore

183 matchBeforeNonBlank

184 matchBeforeNonBlankX

185 matchBeforeX

186 moveLabels

187 navtitle

188 new

189 newTag

190 newText

191 newTree

192 next

193 nextIn

194 nextInX

195 nextNonBlank

196 nextNonBlankX

197 nextOn

198 nextX

199 nn

200 number

201 numbering

202 numberNode

203 numbers

204 numberTree

205 opAt

206 opAttr

207 opBy

208 opContents

209 opGo

210 opNew

211 opPutFirst

212 opPutFirstAssign

213 opPutLast

214 opPutLastAssign

215 opPutNext

216 opPutNextAssign

217 opPutPrev

218 opPutPrevAssign

219 opString

220 ordered

221 orderedX

222 otherprops

223 outputclass

224 over

225 overNonBlank

226 overNonBlankX

227 overX

228 parent

229 parse

230 parser

231 path

232 pathString

233 position

234 present

235 prettyString

236 prettyStringCDATA

237 prettyStringContent

238 prettyStringEnd

239 prettyStringNumbered

240 prev

241 prevIn

242 prevInX

243 prevNonBlank

244 prevNonBlankX

245 prevOn

246 prevX

247 printAttributes

248 printAttributesReplacingIdsWithLabels

249 props

250 putFirst

251 putFirstAsText

252 putFirstAsTextNonBlank

253 putFirstAsTextNonBlankX

254 putFirstNonBlank

255 putFirstNonBlankX

256 putLast

257 putLastAsText

258 putLastAsTextNonBlank

259 putLastAsTextNonBlankX

260 putLastNonBlank

261 putLastNonBlankX

262 putNext

263 putNextAsText

264 putNextAsTextNonBlank

265 putNextAsTextNonBlankX

266 putNextNonBlank

267 putNextNonBlankX

268 putPrev

269 putPrevAsText

270 putPrevAsTextNonBlank

271 putPrevAsTextNonBlankX

272 putPrevNonBlank

273 putPrevNonBlankX

274 reindexNode

275 renameAttr

276 renameAttrValue

277 renew

278 renewNonBlank

279 renewNonBlankX

280 replaceSpecialChars

281 replaceWith

282 replaceWithBlank

283 replaceWithBlankNonBlank

284 replaceWithBlankNonBlankX

285 replaceWithNonBlank

286 replaceWithNonBlankX

287 replaceWithText

288 replaceWithTextNonBlank

289 replaceWithTextNonBlankX

290 restore

291 restoreX

292 save

293 setAttr

294 string

295 stringContent

296 stringNode

297 stringQuoted

298 stringReplacingIdsWithLabels

299 stringWithConditions

300 style

301 tag

302 text

303 through

304 throughX

305 to

306 tree

307 type

308 unwrap

309 unwrapNonBlank

310 unwrapNonBlankX

311 upto

312 uptoX

313 wrapContentWith

314 wrapDown

315 wrapTo

316 wrapToX

317 wrapUp

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