我正在使用 XMLStarlet 为我的应用程序快速部署 cmd (Windows) 脚本,并且我正在更改配置 xml 文件。
对整个节点/属性的操作非常完美,但我需要用特定值替换属性的一部分,例如:
input.xml
:端口是 8000
:
<list>
<address id="a1">
<data url="http://localhost:8000/a1.html" />
</address>
<address id="a2">
<data url="http://localhost:8000/a2.html" />
</address>
</list>
我需要更改
/list/address/data/@url
的端口部分以获得:
所需
output.xml
:端口现在8001
:
<list>
<address id="a1">
<data url="http://localhost:8001/a1.html" />
</address>
<address id="a2">
<data url="http://localhost:8001/a2.html" />
</address>
</list>
任何有关合适的 xmlstarlet 命令的帮助将不胜感激。我不想将 sed 混合到我的脚本中。
使用 XPath 字符串函数、
concat
和 substring-after
:
xmlstarlet ed -u /list/address/data/@url ^
-x "concat('http://localhost:8001/', substring-after(substring-after(., 'http://localhost:'), '/'))" ^
addr-list.xml > new-addr-list.xml
move new-addr-list.xml addr-list.xml
您可以编辑
--inplace
而不是 move
:
xmlstarlet ed --inplace -u /list/address/data/@url ^
-x "concat('http://localhost:8001/', substring-after(substring-after(., 'http://localhost:'), '/'))" ^
addr-list.xml
对于
batch + xmlstarlet
解决方案
@echo off
setlocal enableextensions disabledelayedexpansion
set "count=1"
rem For each url in the xml file
for /f "delims=" %%v in ('
xml sel -t -v "/list/address/data/@url" input.xml
') do (
rem Split the line using colons as delimiters
rem So we have %%a = http %%b = //localhost %%c = 8001/....
for /f "tokens=1,2,* delims=:" %%a in ("%%v") do (
rem Remove the port number from %%c using the numbers as delimiters
for /f "tokens=* delims=0123456789" %%d in ("%%c") do (
rem Here we have all the needed elements. Retrieve the number of the
rem element being updated (with delayed expansion) and update the
rem xml document (without delayed expansion to avoid problems)
setlocal enabledelayedexpansion
for %%n in (!count!) do (
endlocal
xml edit -L -u "/list/address[%%n]/data/@url" -v "%%a:%%b:8003%%d" input.xml
)
)
)
rem This instance has been processed. Increment counter
set /a "count+=1"
)