How do I select and edit an xml node with xmlstartlet?

我只是一个虾纸丫 提交于 2019-12-01 19:31:24
zago

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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!