xmlbatch-filexpathcmdxmlstarlet

XMLStarlet - replace a part of attribute


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.


Solution

  • 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