XSH2 not only provides ways to browse and inspect the DOM tree but also many commands to modify its content by various operations, such as copying, moving, and deleting its nodes as well as creating completely new nodes or XML fragments and attaching them to it. It is quite easy to learn these commands since their names or aliases mimic their well-known filesystem analogies. On the other hand, many of these commands have two versions one of which is prefixed with a letter "x". This "x" stands for "cross", thus e.g. xcopy should be read as "cross copy". Let's explain the difference on the example of xcopy.
In a copy operation, you have to specify what nodes are to be copied and where to, in other words, you have to specify the source and the target. XSH2 is very much XPath-based so, XPath is used here to specify both of them. However, there might be more than one node that satisfies an XPath expression. So, the rule of thumb is that the "cross" variant of a command places one and every of the source nodes to the location of one and every destination node, while the plain variant works one-by-one, placing the first source node to the first destination, the second source node to the second destination, and so on (as long as there are both source nodes and destinations left).
$scratch/>$a := create "<X><A/><Y/><A/></X>";
$a/>$b := create "<X><B/><C/><B/><C/><B/></X>";
$b/>xcopy $a//A replace $b//B;
$b/>copy $b//C before $a//A;
$b/>ls $a;
<?xml version="1.0" encoding="utf-8"?> <X><C/><A/><Y/><C/><A/></X> $b/>ls $b;
<?xml version="1.0" encoding="utf-8"?> <X><A/><A/><C/><A/><A/><C/><A/><A/></X>
As already indicated by the example, another issue of tree modification is the way in which the destination node determines the target location. Should the source node be placed before, after, or somewhere among the children of the resulting node? Or maybe, should it replace it completely? This information has to be given in the location argument that usually precedes the destination XPath.
Now, what happens if source and destination nodes are of incompatible types? XSH2 tries to avoid this by implicitly converting between node types when necessary. For example, if a text, comment, and attribute node is copied into, before or after an attribute node, the original value of the attribute is replaced, prepended or appended respectively with the textual content of the source node. Note however, that element nodes are never converted into text, attribute or any other textual node. There are many combinations here, so try yourself and see the results.
You may even use some more sophisticated way to convert between node types, as shown in the following example, where an element is first commented out and than again uncommented. Note, that the particular approach used for resurrecting the commented XML material works only for well-balanced chunks of XML.
Example 3. Using string variables to convert between different types of nodes
$doc := create <<EOF; <?xml version='1.0'?> <book> <chapter> <title>Intro</title> </chapter> <chapter> <title>Rest</title> </chapter> </book> EOF
# comment out the first chapterls //chapter[1] |> $chapter_xml;
insert comment $chapter_xml replace //chapter[1];
ls / 0;
# OUTPUT: <?xml version="1.0"?> <book> <!-- <chapter> <title>Intro</title> </chapter> --> <chapter> <title>Rest</title> </chapter> </book> # un-comment the chapter$comment = string(//comment()[1]);
insert chunk $comment replace //comment()[1];
ls / 0;
# OUTPUT: <?xml version="1.0"?> <book> <chapter> <title>Intro</title> </chapter> <chapter> <title>Rest</title> </chapter> </book>
change namespace prefix (EXPERIMENTAL)
change namespace URI (EXPERIMENTAL)
clone a given document
copy nodes (in the one-to-one mode)
create a special attribute declaring an XML namespace (EXPERIMENTAL)
Edit parts of a XML document in a text editor.
Edit a string or variable in a text editor.
expression argument type
index selected nodes by some key value
create a node in on a given target location
relative destination specification (such as after, before, etc.)
transform node value/data using Perl or XPath expression
move nodes (in the one-to-one mode)
node type specification (such as element, attribute, etc.)
normalizes adjacent textnodes
load and insert XInclude sections
remove given nodes
quickly rename nodes with in-line Perl code
create or modify document content (EXPERIMENTAL)
set document's DTD declaration
set document's charset (encoding)
set namespace of the current node (EXPERIMENTAL)
set document's standalone flag
sort a given node-list by given criteria
strip leading and trailing whitespace
wrap given nodes into elements
wrap spans of nodes into elements
copy nodes (in the all-to-every mode)
create nodes on all target locations
move nodes (in the all-to-every mode)
XPath expression
compile a XSLT stylesheet and/or transform a document with XSLT
apply XUpdate commands on a document