Reputation: 85
I am using XMLStarlet for a quick deploy cmd (Windows) script for my app, and I am changing the configuration xml file.
Manipulation of the whole nodes/attributes works just perfect, but I need to replace a part of an attribute with a specific value, for example:
Input: addr-list.xml
: port is 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>
I need to change the port part of a /list/address/data/@url
to get:
Desired output: new-addr-list.xml
: port is now 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>
Any help with a suitable xmlstarlet command would be much appreciated. I don't want to mix sed into my script.
Upvotes: 2
Views: 1603
Reputation: 5027
Using XPath string functions, concat
and 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
You can edit --inplace
instead of move
:
xmlstarlet ed --inplace -u /list/address/data/@url ^
-x "concat('http://localhost:8001/', substring-after(substring-after(., 'http://localhost:'), '/'))" ^
addr-list.xml
Upvotes: 2
Reputation: 70923
For a batch + xmlstarlet
solution
@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"
)
Upvotes: 0