
我有一個 SVG 文件,它是一個 XML 文件:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape">
<defs
id="defs2">
<!-- a lot of stuff> </defs>
<!-- more stuff-->
</svg>
我想將 svg: 前綴添加到與預設命名空間對應的所有標籤中,以獲得下一個輸出:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg:svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape">
<svg:defs
id="defs2">
<!-- a lot of stuff> </svg:defs>
<!-- more stuff-->
</svg:svg>
我確信這可以在 shell 的一個或幾個命令列中使用xmllint和/或xmlstarlet但我無法管理它。
答案1
自從你問起以來已經有一段時間了。儘管如此 ...
xmlstarlet edit
's -r
/--rename
操作需要新名稱的文字值,因此 XPath 函數已不再適用。但是,xmlstarlet select
可以用作程式碼產生器來產生編輯命令:
xmlstarlet select -t \
--var sq -o "'" -b \
-o 'xmlstarlet edit --pf \' -n \
-m 'set:distinct(//_:*)' \
-o ' -r ' -v 'concat($sq,"//_:",local-name(),$sq)' \
-o ' -v ' -v 'concat($sq,"svg:",local-name(),$sq)' -o ' \' -n \
-b \
-f -n \
file.xml
在哪裡
- 表達式
//_:*
匹配預設命名空間中的所有元素節點(_
捷徑位於xmlstarlet
使用者手冊) - EXSLT 函數
set:distinct
消除重複 -o
輸出字串文字、-n
換行符、-f
輸入路徑名/URL(但-
對於標準輸入)-b
結束目前容器(-m
,--var
without=
, ao)- 在列出生成的 XSLT 程式碼之前新增一個
-C
選項-t
輸出:
xmlstarlet edit --pf \
-r '//_:svg' -v 'svg:svg' \
-r '//_:defs' -v 'svg:defs' \
file.xml
在哪裡
-P
/--pf
保留原始格式- 在支援就地編輯 後新增
-L
/選項(不在使用者指南中,而是在--inplace
edit
xmlstarlet.txt)
要將輸出作為 shell 腳本執行:
xmlstarlet-select-command | sh -s > result.xml
如果您想避免 EXSLT,請改為-m '//_:*' --sort 'A:T:-' .
透過管道輸出uniq
,或簡單地-m '//_:*'
使用可能的重複項。
答案2
xmlstarlet
以特別殘酷的方式使用(我等待正確的 xpath)
for x in $(xmlstarlet sel -t -m "//*" -n -v "name()" file1.xml | sort | uniq); do
xmlstarlet ed -r "//svg:$x" -v "svg:$x" file1.xml > tmp.xml;
mv tmp.xml file1.xml;
done
由於您已經聲明了命名空間svg
,因此您需要在 中呼叫它來xpath
更改節點名稱的文字值。