How do I select and edit an xml node with xmlstartlet?
Here I'm selecting the node:
$ xmlstarlet sel -t -c "/configuration/property[name='http.agent.name']"/value conf/nutch-default.xml
<value/>
This doesn't edit it:
$ xmlstarlet edit "/configuration/property[name='http.agent.name']"/value -v 'test' conf/nutch-default.xml
I/O warning : failed to load external entity "/configuration/property[name='http.agent.name']/value"
What would be an xmlstartlet command that does change the change? AFAIK -x is not supported in xmlstartlet yet.
I'm working开发者_运维知识库 on conf/nutch-default.xml
$ xmlstarlet ed --help
XMLStarlet Toolkit: Edit XML document(s)
Usage: xml ed <global-options> {<action>} [ <xml-file-or-uri> ... ]
where
<global-options> - global options for editing
<xml-file-or-uri> - input XML document file name/uri (stdin otherwise)
<global-options> are:
-P (or --pf) - preserve original formatting
-S (or --ps) - preserve non-significant spaces
-O (or --omit-decl) - omit XML declaration (<?xml ...?>)
-N <name>=<value> - predefine namespaces (name without 'xmlns:')
ex: xsql=urn:oracle-xsql
Multiple -N options are allowed.
-N options must be last global options.
--help or -h - display help
where <action>
-d or --delete <xpath>
-i or --insert <xpath> -t (--type) elem|text|attr -n <name> -v (--value) <value>
-a or --append <xpath> -t (--type) elem|text|attr -n <name> -v (--value) <value>
-s or --subnode <xpath> -t (--type) elem|text|attr -n <name> -v (--value) <value>
-m or --move <xpath1> <xpath2>
-r or --rename <xpath1> -v <new-name>
-u or --update <xpath> -v (--value) <value>
-x (--expr) <xpath> (-x is not implemented yet)
XMLStarlet is a command line toolkit to query/edit/check/transform
XML documents (for more information see http://xmlstar.sourceforge.net/)
$ xmlstarlet --version
1.0.1
You may read the entire contents of nutch-default.xml to a variable, edit the contents of that variable with xmlstarlet and then write the result back to nutch-default.xml again.
Another way would be to use open file handles as described in Redirect output from sed 's/c/d/' myFile to myFile .
xmlstarlet --version # 1.0.6
xmlstarlet ed --help | less -Ip 'inplace'
# 1.
# in-place version using xmlstarlet only
curl -L -s -o nutch-default.xml 'http://svn.apache.org/viewvc/nutch/branches/branch-1.3/conf/nutch-default.xml?view=co&revision=1079746&content-type=text%2Fplain'
xmlstarlet edit -L -u "/configuration/property[name='http.agent.name']"/value -v 'test' nutch-default.xml
xmlstarlet sel -t -c "/configuration/property[name='http.agent.name']"/value nutch-default.xml
# 2.
# variable version
curl -L -s -o nutch-default.xml 'http://svn.apache.org/viewvc/nutch/branches/branch-1.3/conf/nutch-default.xml?view=co&revision=1079746&content-type=text%2Fplain'
xmlstr="$(< nutch-default.xml)" # save file contents to variable
printf '%s\n' "$xmlstr" |
xmlstarlet edit -u "/configuration/property[name='http.agent.name']"/value -v 'test' > nutch-default.xml
xmlstarlet sel -t -c "/configuration/property[name='http.agent.name']"/value nutch-default.xml
# 3.
# file handle version
# cf. https://stackoverflow.com/questions/2585438/redirect-output-from-sed-s-c-d-myfile-to-myfile
curl -L -s -o nutch-default.xml 'http://svn.apache.org/viewvc/nutch/branches/branch-1.3/conf/nutch-default.xml?view=co&revision=1079746&content-type=text%2Fplain'
exec 3<nutch-default.xml
rm nutch-default.xml # prevent open file from being truncated
xmlstarlet edit -u "/configuration/property[name='http.agent.name']"/value -v 'test' <&3 >nutch-default.xml
xmlstarlet sel -t -c "/configuration/property[name='http.agent.name']"/value nutch-default.xml
The documentation is very very poor. I stumbled across Stackoverflow for more than a day and after reading through many answers on stack overflow I finally derived the solution for "edit file inplace option" for the value of an element with namespaces defined. Given an XML as below:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<cassandra xmlns="http://venus.com/ns/mibs/VENUS-MODE/1.0">
<clusterName>test-cluster</clusterName>
<cassandraUsername>simba</cassandraUsername>
<cassandraPassword>U2FsdGVkX1/Zc4NAsF59coYZLaCgddJ9b91s016HUbs=</cassandraPassword>
<cassandraService>Local</cassandraService>
</cassandra>
<monit xmlns="http://venus.com/ns/mibs/VENUS-MODE/1.0">
<cpuUsageThreshold>70</cpuUsageThreshold>
<cpuUsageThresholdClear>60</cpuUsageThresholdClear>
<memoryUsageThreshold>70</memoryUsageThreshold>
<memoryUsageThresholdClear>60</memoryUsageThresholdClear>
</monit>
</config>
The xmlstarlet command to modify /config/cassandra/clusterName element value would be:
xmlstarlet ed -L -N x="http://venus.com/ns/mibs/VENUS-MODE/1.0" -u "//config/x:cassandra/x:cassandraPassword" -v "test123" Myfile.xml
Remember ed & -L option must precede -N (namespace) option. Hope this helps somebody looking for edit file inplace option with namespace issues.
My version of xmlstarlet
needs an action
option to the edit
command. If you want to update the node with a new value you have to specify -u
, e.g.:
xmlstarlet edit -u "/configuration/property[name='http.agent.name']"/value -v 'test' conf/nutch-default.xml
精彩评论