bash 如何使用 xmlstartlet 选择和编辑 xml 节点?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5591414/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 23:46:01  来源:igfitidea点击:

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

xmlbashcommand-line-interface

提问by simpatico

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.

什么会改变更改的 xmlstartlet 命令?AFAIK -x 在 xmlstartlet 中尚不支持。

I'm working on conf/nutch-default.xml

我正在处理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

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

您可以将 nutch-default.xml 的全部内容读取到一个变量中,使用 xmlstarlet 编辑该变量的内容,然后再次将结果写回 nutch-default.xml。

Another way would be to use open file handles as described in Redirect output from sed 's/c/d/' myFile to myFile.

另一种方法是使用打开的文件句柄,如将输出从 sed 's/c/d/' myFile 重定向到 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 

回答by vinod kumar

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:

文档非常非常差。我偶然发现了 Stackoverflow 超过一天,在阅读了许多关于堆栈溢出的答案后,我终于为定义了命名空间的元素的值推导出了“就地编辑文件选项”的解决方案。给定一个 XML,如下所示:

<?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:

修改 /config/cassandra/clusterName 元素值的 xmlstarlet 命令是:

xmlstarlet ed -L -N x="http://venus.com/ns/mibs/VENUS-MODE/1.0" -u "//config/x:cassandra/x:cassandraPassword" -v "test123" Myfile.xml

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.

记住 ed & -L 选项必须在 -N(命名空间)选项之前。希望这有助于寻找具有命名空间问题的就地编辑文件选项的人。

回答by bmk

My version of xmlstarletneeds an actionoption to the editcommand. If you want to update the node with a new value you have to specify -u, e.g.:

我的版本xmlstarlet需要命令的action选项edit。如果要使用新值更新节点,则必须指定-u,例如:

xmlstarlet edit -u "/configuration/property[name='http.agent.name']"/value -v 'test' conf/nutch-default.xml