lxreplace — Make replacements or deletions in an XML document
lxreplace
[
-xmlns[:prefix]=uri
...]
-q target-query
[
-r replace-query
|
-t template
|
-n rename-query
|
-a add-query
|
-@ attr-name-query attr-value-query
|
-d
] [
input-file
]
lxreplace allows nodes in an XML document (elements, attributes and text) to be replaced, deleted, or renamed. The nodes to be changed are specified by an XPath. Their replacements are specified by either an XPath expression or an XSLT template.
The input-file argument may be a URI instead of a filename. If no input-file argument is given, standard input is used.
binds a prefix (or the default namespace) to a URI for use in XPath queries.
an XPath specifying the nodes to be processed. Nodes that match the
target-query
are processed; the others are left unchanged. How the
nodes are processed depends on which of the -r
,
-t
, -n
, and
-d
flags is used.
Unless the -t
is used, this query is streamed.
an XPath which is used to construct the replacement for matched
nodes. The replace-query
is evaluated relative
to the matched node. If the result is an element then it is processed
recursively before replacing the original matched node.
If the matched node is an attribute, then it is deleted if the
replace-query
returns an empty node
set. Otherwise the value of the attribute is replaced by the string
value of the result.
an XSLT template which is used to construct the replacement for matched
nodes. This is done by constructing an XSLT stylesheet containing the
template in a rule whose match attribute is the
target-query
.
In the stylesheet, the prefix xsl
is bound to the
XSL namespace. A low-priority template rule is included that provides
an identity transform for nodes not matched by the template. For
convenience, a number of entities are defined for use in the template:
Copies the current node and recursively processes its attributes and children.
Equivalent to
<xsl:copy><xsl:apply-templates select='@*|node()'/></xsl:copy>
.
Processes the attributes of the current node.
Equivalent to
<xsl:apply-templates select='@*'/>
Processes the children of the current node.
Equivalent to
<xsl:apply-templates select='node()'/>
.
Copies the text of the current node.
Equivalent to
<xsl:value-of select='.'/>
.
Inserts a space character.
Equivalent to
<xsl:text> </xsl:text>
.
Inserts a newline character.
Equivalent to
<xsl:text> </xsl:text>
.
an XPath which is used to rename the matched nodes. The
rename-query
is evaluated relative to the
matched node and the result is interpreted as a QName. A QName
(qualified name) is either a plain name such as table or a prefixed
name such as xhtml:table.
Only elements and attributes can be renamed.
an XPath which is used to construct nodes to be added to the matched nodes,
which must be elements. The
add-query
is evaluated relative to the
matched node. The result must be a node-set
and the nodes are added to the matched node as attributes or children.
If multiple attributes with the same name are added, the one last in
document order wins.
two XPaths which are used to construct the names and values of attributes
to be added to the matched nodes, which must be elements.
The attr-name-query
is evaluated relative to
the matched node and the result interpreted as a QName, the name
of a new attribute to be added.
The attr-value-query
is evaluated relative to
the matched node and is converted to a string and used as the value of
the new attribute.
Any existing attribute with the same name is replaced.
This causes the matched nodes to be simply deleted, rather than
replaced. It is equivalent to "-r expr
"
where expr
is an XPath that selects an empty node
set.
If none
of -r
, -t
,
-n
, -@
, and -d
is given the effect is equivalent to "-r node()
",
which replaces matched nodes with their children. That is, it
"unwraps" the children of the nodes.
It is usually necessary to quote the query and template arguments
because they contain characters significant to the shell such as
*
.
It is generally best to use single quotes for this, and use double quotes
when needed inside the value. In some cases it is quite difficult to find
an appropriate quoting.
If you need an XPath whose value is a fixed string (as is commonly the case
when renaming elements and attributes), you must
doubly quote it; for example '"foo"'
. The outer quotes are
consumed by the shell, so if you used 'foo'
the XPath would
evaulate to any <foo>
children of the current node
instead of to the string "foo"
.
Except when -t
is used, lxreplace streams the input document, so that only the
subtree rooted at the matched node and its ancestors are accessible
when the
replace-query
,
rename-query
, or
add-query
is evaluated. If it is necessary to access
other parts of the document to construct the replacement, use the
-t
form instead.
lxreplace -q '*'
This replaces all elements with their children, in effect deleting all element markup.
lxreplace -q 'meta' -d
This deletes all <meta>
elements.
lxreplace -q entity -n '"ent"'
This changes the name of all <entity>
elements to
ent
. Note the double quoting.
lxreplace -q entity -n @type
This changes the name of all <entity>
elements to
the value of their type attribute.
lxreplace -q entity -t '<entity text="{.}">&attrs;&children;</entity>'
This adds an attribute text
to all <entity>
elements,
whose value is the text content of the element.
This will only work if the element doesn't already have a
text
attribute, otherwise the old value will be copied back
by the call to &attrs;
. We could avoid this by using
a more complicated template:
lxreplace -q entity -t '<entity>&attrs;<xsl:attribute name="text">&text;</xsl:attribute>&children;</entity>'
which constructs the name attribute after copying the old ones.
lxreplace -q entity -r @text
This replaces all <entity>
elements with the
value of their text
attribute.
lxreplace -q w -a 'w/@*'
This adds the attributes from any nested <w>
elements
to their parent <w>
elements.
lxreplace -q w -@ '"text"' .
This adds an attribute called text to all <w>
elements,
with a value equal to the text content of the element. Note the double quoting.