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

匿名 (未验证) 提交于 2019-12-03 02:31:01

问题:

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 

回答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  


回答2:

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.



回答3:

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 


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