XMLStarlet - 替换部分属性

问题描述 投票:0回答:2

我正在使用 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 混合到我的脚本中。

xml batch-file xpath cmd xmlstarlet
2个回答
2
投票

使用 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

0
投票

对于

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"
    )
© www.soinside.com 2019 - 2024. All rights reserved.