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

Synopsis
     use Data::Edit::Xml;

     say STDERR Data::Edit::Xml::new(inputString=><<END)->                          # Docbook
    <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

     by(sub                                                                         # Transform Docbook to Dita
      {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;
        }
      })->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));
      })->string =~ s/></>\n</gr;

     # Dita (after being formatted for easier reading):
     #
     # <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
  Constructor
   new()
    New parse - call this method statically as in Data::Edit::Xml::new()
    with keyword parameters=> chosen from:

      Parameter   Description
      inputString => string of xml to be parsed
      inputFile   => file of xml to be parsed
      name        => symbolic name for this parse used in messages about this parse and to name output files generated by this parse
      output      => directory into which to write output files
      errors      => sub directory of 'output' into which to write a copy of the string to be parsed in the event that an xml parse error is encountered while parsing this string

   newText()
    Create a new text node which can then be inserted into a parse tree

         Parameter  Description
      1  $tree      Parse tree in which to create the new text node
      2  $text      Text of the new node

   newTag()
    Create a new non text node which can then be inserted into a parse tree

         Parameter   Description
      1  $tree       Parse tree in which to create the new node
      2  $tag        Tag for the new node
      3  %attributes attributes for the node

   Data::Edit::Xml::newTree()
    Create a new non text root node to create a new parse tree into which
    other nodes can be inserted

         Parameter   Description
      1  $tag        Tag for the new node
      2  %attributes attributes for the node

   cdata()
    The name of the command name to use to represent text

  Stringification
    Print the parse tree

   string($node)
    Build a string from a node of a parse tree and the nodes below it

         Parameter  Description
      1  $node      Start node

   contentString($node)
    Build a string from the contents of a node

         Parameter  Description
      1  $node      Start node

   prettyString($node)
    Build a readable, prettified string from a node of a parse tree and the
    nodes below it

         Parameter  Description
      1  $node      Start node

   PrettyContentString($node)
    Build a readable, prettified string from the content of a node

         Parameter  Description
      1  $node      Start node

   stringWithCondition($node, @conditions)
    Build a string from a node of a parse tree and the nodes below it
    subject to conditions to reject some nodes

         Parameter    Description
      1  $node        Start node
      2  @conditions  conditions in effect

   addConditions($node, @conditions)
    Add conditions to a node

         Parameter    Description
      1  $node        Node
      2  @conditions  conditions to add

   deleteConditions($node, @conditions)
    Delete conditions applied to a node

         Parameter    Description
      1  $node        Node
      2  @conditions  conditions to add

   listConditions($node)
    List conditions applied to a node

         Parameter  Description
      1  $node      Node

   isText($node)
    Is this a text node?

         Parameter  Description
      1  $node      Node to test

  Attributes
    Get or set attributes

   attr :lvalue($node, $attribute)
    Value of attribute in current command

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

   attrs($node, @attributes)
    Get the value of zero or more attributes

         Parameter   Description
      1  $node       Node in parse tree
      2  @attribute  attribute names whose values are to be retrieved

   attrCount($node)
    Get the number of attributes for a node

         Parameter   Description
      1  $node       Node in parse tree

   setAttr($node, %values)
    Set the value of an attribute in a command

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

  Contents
    Contents of the current node

   contents($node)
    Get all the nodes contained by this node as an array (not an array
    reference)

         Parameter  Description
      1  $node      Node

   contentBeyond($node)
    Get all the nodes beyond this node at the level of this node

         Parameter  Description
      1  $node      Node

   contentBefore($node)
    Get all the nodes before this node at the level of this node

         Parameter  Description
      1  $node      Node

   contentAsTags($node)
    Get the tags of all the nodes contained by this node as a string

         Parameter  Description
      1  $node      Node

   contentBeyondAsTags($node)
    Get the tags of all the nodes beyond this node as a string

         Parameter  Description
      1  $node      Node

   contentBeforeAsTags($node)
    Get the tags of all the nodes before this node as a string

         Parameter  Description
      1  $node      Node

   position($node)
    Find the position of a node in its parent's content

         Parameter  Description
      1  $node      Node

   index($node)
    Find the position of a node in its parent's index

         Parameter  Description
      1  $node      Node

  Navigation
    Move around in the parse tree

   context($node)
    Tags of this node and its ancestors joined to make a string

         Parameter  Description
      1  $node      Node

   get($node, @position)
    Get a sub node under the current node by its position in each index with
    position zero assumed if no position is supplied

         Parameter  Description
      1  $node      Node
      2  @position  position specification: (index

   c($node, $tag, $position)
    Get all the nodes with the tag of the specified name below the current
    node

         Parameter  Description
      1  $node      Node
      2  $tag       tag
      3  $position

   first($node)
    Get the first node below this node

         Parameter  Description
      1  $node      Node

   firstOf($node, @tags)
    Get the first node below this node

         Parameter  Description
      1  $node      Node
      2  @tags      The tags for the nodes under this node for which we want the first elements

   last($node)
    Get the last node below this node

         Parameter  Description
      1  $node      Node

   isFirst($node)
    Is this node first under its parent?

         Parameter  Description
      1  $node      Node

   isLast($node)
    Is this node last under its parent?

         Parameter  Description
      1  $node      Node

   isOnlyChild($node)
    Is this the only child of its parent?

         Parameter  Description
      1  $node      Node

   isEmpty($node)
    Check whether the node is empty

         Parameter  Description
      1  $node      Start node

   next($node)
    Get the node next to the current node

         Parameter  Description
      1  $node      Node

   prev($node)
    Get the node previous to the current node

         Parameter  Description
      1  $node      Node

   by($node, $sub, @context)
    Post-order traversal of a parse tree or sub tree

         Parameter  Description
      1  $node      Starting node
      2  $sub       sub to call for each sub node
      3  @context   accumulated context

   down($node, $sub, @context)
    Pre-order traversal down through a parse tree or sub tree

         Parameter  Description
      1  $node      Starting node
      2  $sub       sub to call for each sub node
      3  @context   accumulated context

   at()
    Check the node is in the context specified by the array of tags from the
    ancestors going up the parse tree from the node

   over($node, $re)
    Match the tags at the level below a node against a regular expression

         Parameter  Description
      1  $node      Node
      2  $re        regular expression

   after($node, $re)
    Match the tags in the current level after a node against a regular
    expression

         Parameter  Description
      1  $node      Node
      2  $re        regular expression

   before($node, $re)
    Match the tags in the current level before a node against a regular
    expression

         Parameter  Description
      1  $node      Node
      2  $re        regular expression

   up($node, @tags)
    Go up to a specified context

         Parameter  Description
      1  $node      Start node
      2  @tags      tags identifying context

  Editing
    Edit the data in the parse tree

   change($node, $name, @tags)
    Change the name of a node in an optional tag context

         Parameter  Description
      1  $node      Node
      2  $name      new name
      3  @tags      tags defining the context

   deleteAttr($node, $attr, $value)
    Delete the attribute, optionally checking its value first

         Parameter  Description
      1  $node      Node
      2  $attr      attribute name
      3  $value     optional attribute value to check first

   deleteAttrs($node, @attrs)
    Delete the named attributes if present, without checking their values
    first

         Parameter  Description
      1  $node      Node
      2  @attr      Attributes to delete

   renameAttr($node, $old, $new)
    Change the name of an attribute regardless of whether the new attribute
    already exists

         Parameter  Description
      1  $node      Node
      2  $old       existing attribute name
      3  $new       new attribute name

   changeAttr($node, $old, $new)
    Change the name of an attribute unless it is already there

         Parameter  Description
      1  $node      Node
      2  $old       existing attribute name
      3  $new       new attribute name

   renameAttrValue($node, $old, $oldValue, $new, $newValue)
    Change the name and value of an attribute regardless of whether the new
    attribute already exists

         Parameter  Description
      1  $node      Node
      2  $old       existing attribute name and value
      3  $oldValue  new attribute name and value
      4  $new
      5  $newValue

   changeAttrValue($node, $old, $oldValue, $new, $newValue)
    Change the name and value of an attribute unless it is already there

         Parameter  Description
      1  $node      Node
      2  $old       existing attribute name and value
      3  $oldValue  new attribute name and value
      4  $new
      5  $newValue

   Structure
    Change the structure of the parse tree

   wrapWith($old, $tag)
    Wrap the original node in a new node forcing the original node down
    deepening the parse tree

         Parameter  Description
      1  $old       Node
      2  $tag       tag for new node

   wrapUp($node, @tags)
    Wrap the original node in a sequence of new nodes forcing the original
    node down deepening the parse tree

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

   wrapContentWith($old, $tag)
    Wrap the content of a node in a new node, the original content then
    contains the new node which contains the original node's content

         Parameter  Description
      1  $old       Node
      2  $tag       tag for new node

   unwrap($node)
    Unwrap a node by inserting its content into its parent at the point
    containing the node

         Parameter  Description
      1  $node      Node to unwrap

   replaceWith($old, $new)
    Replace a node (and all its content) with a new node (and all its
    content)

         Parameter  Description
      1  $old       Old node
      2  $new       new node

   Cut and Put
    Move nodes around in the parse tree

   cut($node)
    Cut out a node - remove the node from the parse tree and return it so
    that it can be put else where

         Parameter  Description
      1  $node      Node to  cut out

   putNext($old, $new)
    Place the new node just after the original node in the content of the
    parent

         Parameter  Description
      1  $old       Original node
      2  $new       new node

   putPrev($old, $new)
    Place the new node just before the original node in the content of the
    parent

         Parameter  Description
      1  $old       Original node
      2  $new       new node

   putFirst($old, $new)
    Place the new node at the front of the content of the original node

         Parameter  Description
      1  $old       Original node
      2  $new       new node

   putLast($old, $new)
    Place the new node at the end of the content of the original node

         Parameter  Description
      1  $old       Original node
      2  $new       new node

Index of methods by name
    "addConditions($node, @conditions)" "after($node, $re)" "at()" "attr
    :lvalue($node, $attribute)" "attrCount($node)" "attrs($node,
    @attributes)" "before($node, $re)" "by($node, $sub, @context)" "c($node,
    $tag, $position)" "cdata()" "change($node, $name, @tags)"
    "changeAttr($node, $old, $new)" "changeAttrValue($node, $old, $oldValue,
    $new, $newValue)" "contentAsTags($node)" "contentBefore($node)"
    "contentBeforeAsTags($node)" "contentBeyond($node)"
    "contentBeyondAsTags($node)" "contents($node)" "contentString($node)"
    "context($node)" "cut($node)" "deleteAttr($node, $attr, $value)"
    "deleteAttrs($node, @attr)" "deleteConditions($node, @conditions)"
    "first($node)" "firstOf($node, @tags)" "get($node, @position)"
    "index($node)" "isEmpty($node)" "isFirst($node)" "isLast($node)"
    "isOnlyChild($node)" "isText($node)" "last($node)"
    "listConditions($node)" "new()" "newTag()" "newText()"
    "Data::Edit::Xml::newTree()" "next($node)" "over($node, $re)"
    "position($node)" "prev($node)" "PrettyContentString($node)"
    "prettyString($node)" "putFirst($old, $new)" "putLast($old, $new)"
    "putNext($old, $new)" "putPrev($old, $new)" "renameAttr($node, $old,
    $new)" "renameAttrValue($node, $old, $oldValue, $new, $newValue)"
    "replaceWith($old, $new)" "setAttr($node, %values)" "string($node)"
    "stringWithCondition($node, @conditions)" "unwrap($node)" "up($node,
    @tags)" "wrapContentWith($old, $tag)" "wrapUp($old, @tags)"
    "wrapWith($old, $tag)"

Installation
    This module is written in 100% Pure Perl and is thus 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.

