wrap [--namespace expression]
[ [--inner] | [--while|:W expression] [--until|:U expression]
[--skip-whitespace|:w] [--skip-comments|:c] [--skip-pi|:p] ]
expression xpath
For each node matching the xpath argument, this command creates a new element node according to a given expression (in the same way as xinsert does) which replaces the matching node, and moves the matching node into this newly created element. If namespace expression is given, the namespace is applied on the created element. The command returns a node-list consisting of the elements created.
With --inner
(or :i
)
flag the command
wraps children nodes of the matching node
rather than the node it self
the following sense:
for each matching node
a new element node is created,
but this time it is placed into
the matching node and
all previous children of the matching node
are moved into the newly created node.
In this mode, all non-element matching
nodes are ignored. This flag cannot be used together
with --while
and --until
, which we describe next.
--while
(:W
)
and/or --until
(:U
)
arguments can be provided in order to move a sequence
of adjacent siblings following the matching node into
the newly created element. In this way the newly created element wraps
not just the matching node itself but a range of nodes starting
at the matching node and ending either before a first following node matching
the expression of --until
, or
before a first following node not matching the expression
of --while
, or at the last sibling if
neither of the prior apply. Both these expressions are
evaluated in the context of the currently tested sibling and prior to
the creation of the wrapping element. The context
position for these expressions is 1 at the first sibling
following the matching node and increases with each tested
sibling; the context size is the number of all
siblings following the matching node.
It is important to mention that siblings wrapped in this
way are excluded from further processing by wrap even if included in the node-list
produced by the xpath argument. This allows to easily wrap
certain adjacent elements without worrying about some
elements being wrapped multiple times
(for example, wrap :W x y //x
wraps
each sequence of adjacent elements <x>
in a <y>
).
--skip-whitespace
(:w
),
--skip-comments
(:c
), and
--skip-pi
(:p
) can be used
in combination with --while
(:W
)
and/or --until
(:U
)
to skip testing the expressions on white-space text
nodes, comments, and/or processing instruction, respectively.
Such nodes are only included in the wrapped range if
followed by a sibling that is to be wrapped.
$scratch/> ls /; <?xml version="1.0" encoding="utf-8"?> <scratch/> $scratch/> wrap 'foo' *; $scratch/> insert attribute 'bar=baz' into /foo; $scratch/> insert text 'some text' into //scratch; $scratch/> wrap --namespace 'http://foo/bar' 'a:A' //@*; $scratch/> $wrapper := wrap 'text aaa="bbb"' //text(); $scratch/> wrap '<elem ccc=ddd>' //*; $scratch/> ls /; <?xml version="1.0" encoding="utf-8"?> <elem ccc="ddd"> <foo xmlns:a="http://foo/bar"> <elem ccc="ddd"> <scratch> <elem ccc="ddd"> <text aaa="bbb">some text</text> </elem> </scratch> </elem> <elem ccc="ddd"> <a:A xmlns:a="http://foo/bar" bar="baz"/> </elem> </foo> </elem> $scratch/> ls $wrapper; <text aaa="bbb">some text</text> $scratch/> wrap --inner bar //foo $scratch/> ls /; <?xml version="1.0" encoding="utf-8"?> <elem ccc="ddd"> <foo xmlns:a="http://foo/bar"> <bar> <elem ccc="ddd"> <scratch> <elem ccc="ddd"> <text aaa="bbb">some text</text> </elem> </scratch> </elem> <elem ccc="ddd"> <a:A xmlns:a="http://foo/bar" bar="baz"/> </elem> </bar> </foo> </elem>
Example 56. Wrapping a range of adjacent nodes
# prepare the test document $scratch/> rm /scratch/node(); # cleanup the document $scratch/> set /scratch/li[5]; # create 5 <li> elements $scratch/> set /scratch/li[3]/following-sibling::li; # add <br/> after the 3rd <li> $scratch/> for //li set . position(); # number the <li> elements $scratch/> ls / <?xml version="1.0" encoding="utf-8"?> <scratch> <li>1</li> <li>2</li> <li>3</li> <br/> <li>4</li> <li>5</li> </scratch> # wrap adjacent elements <li> into an <ol> $scratch/> wrap --skip-whitespace --while self::li ol //li; $scratch/> ls / <?xml version="1.0" encoding="utf-8"?> <scratch> <ol> <li>1</li> <li>2</li> <li>3</li> </ol> <br/> <ol> <li>4</li> <li>5</li> </ol> </scratch>