0

I have XML file myConfig.xml.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<test1.test.com id="valueTest1"/>
<test2.test.com id="valueTest1"/>
<test3.test.com id="valueTest1"/>
<installpath>C:\Temp\TESTxyz</installpath>
<userInput>
<entry key="myPassword" value="Qwerty123!"/>
<entry key="myLogin" value="John"/>
</userInput>

I need in CMD in batch script change value in .

@echo off
setlocal EnableDelayedExpansion
set newValueInstallpath="D:\Work"

(for /F "delims=" %%a in (myConfig.xml) do (
set "line=%%a"
set "newLine=!line:installpath>=!"
if "!newLine!" neq "!line!" (
    set "newLine=<installpath>%newValueInstallpath%</installpath>"
)
echo !newLine!
)) > NEW_myConfig.xml

OUTPUT - NEW_myConfig.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<test1.test.com id="valueTest1"/>
<test2.test.com id="valueTest1"/>
<test3.test.com id="valueTest1"/>
<installpath>D:\Work</installpath>
<userInput>
<entry key="myPassword" value="Qwerty123"/>
<entry key="myLogin" value="John"/>
</userInput>

Change value in installpath is correctly changed BUT value in myPassword cut character "!". How to make it not cut my mark "!"

aschipfl
  • 33,626
  • 12
  • 54
  • 99
mAsHER
  • 15
  • 7
  • 1
    As the line you're modifying does not carry an exclamation mark/exclamation point/bang, `!` the obvious solution, in this case, would be to modify and output only the `!line!` you require, and use `%%a` for the others. – Compo May 15 '20 at 12:25

2 Answers2

1

Delayed expansion is the last thing that happens prior to execution, even after expansion of for meta-variables. When now such a for meta-variable contains a value with an exclamation mark this is going to be consumed by delayed expansion. The solution is to toggle delayed expansion so that it is enabled only when it is needed and disabled otherwise:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "newValueInstallpath=D:\Work"

(for /F "usebackq delims=" %%a in ("myConfig.xml") do (
    set "line=%%a"
    setlocal EnableDelayedExpansion
    set "newLine=!line:installpath>=!"
    if "!newLine!" neq "!line!" (
        set "newLine=<installpath>!newValueInstallpath!</installpath>"
    )
    echo(!newLine!
    endlocal
)) > "NEW_myConfig.xml"

endlocal
aschipfl
  • 33,626
  • 12
  • 54
  • 99
0

You are effectively cutting the ! expansion character yourself by enabling delayed expansion prior to setting the value.

To preserve the ! value, disable delayed expansion until after values have been assigned, at which point you can then Enable it without losing !

A short example:

@Echo Off
    For %%A in ("Installpath>Example" "Installpath>of" "Installpath>Expansion Preservation!") Do Call :Assign "%%~A"
    Setlocal EnableDelayedExpansion
    For /L %%I in (1,1,%Count%) Do Echo(!Line[%%I]!
    Pause
Exit /B

:Assign
    SetLocal DisableDelayedExpansion
    Set "Line=%~1"
    Set "Line=%Line:Installpath>=%"
    Set /A Count+=1
    Endlocal & Set "Line[%Count%]=%Line%" & Set "Count=%Count%"
Exit /B
T3RR0R
  • 2,747
  • 3
  • 10
  • 25