2011-04-08 33 views
3

在這裏,我選擇節點:如何使用xmlstartlet選擇和編輯xml節點?

$ xmlstarlet sel -t -c "/configuration/property[name='http.agent.name']"/value conf/nutch-default.xml 
<value/> 

這並不編輯:

$ 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" 

什麼將是一個xmlstartlet命令確實改變了變化? AFAIK -x在xmlstartlet中不受支持。

我的工作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 

回答

4

你可以閱讀的Nutch-default.xml中的全部內容到一個變量,編輯與xmlstarlet該變量的內容然後再將結果寫回nutch-default.xml。

另一種方法是使用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 
+0

謝謝!我有$ sudo端口升級xmlstarlet,現在我設法使用-L,它符合預期。 – simpatico 2011-04-10 06:08:53

1

我的xmlstarlet版本需要一個action選項來edit命令。如果您想更新爲新值的節點必須指定-u,如:

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

@bmk:你說得對!但現在打印到標準輸出,-L應修改文件,但顯然不在我的版本。我還能怎樣?使用>重定向輸出僅清空文件 – simpatico 2011-04-08 07:25:33

+0

@simpatico:我的'xmlstarlet'版本似乎沒有任何'-L'選項。你能給我完整的命令行嗎?然後我會更新我的答案。 – bmk 2011-04-08 07:27:04

+0

@bmk:我的版本都沒有,我指的是http://stackoverflow.com/questions/1554143/bash-script-to-edit-xml-file。我們還可以如何使用更新修改文件? – simpatico 2011-04-08 07:35:57

2

該文檔非常差。我偶然發現了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> 

的xmlstarlet命令來修改/配置/卡桑德拉/ CLUSTERNAME元件值將是:

xmlstarlet編-L -N X =「HTTP://金星。 COM/NS /的MIB/VENUS-MODE/1.0" -u 「//配置/ X:卡桑德拉/ X:cassandraPassword」 -v 「test123」 myfile.xml中

記住編& -L選項必須先-N(命名空間)選項。希望這有助於有人尋找與名稱空間問題的編輯文件就地選項。