2016-04-28 81 views
2

我正在嘗試創建用於修改xml文件的腳本。 在此XML文件,我有些線路是這樣的:批量替換參數中的值

<tag parameter="value" versionNumber="2.0.3" anotherParameter="value"> 

,我想用一個新的來代替VERSIONNUMBER的價值。

我對通過不同的路線有任何問題,但我正在努力應對價值變化。 任何想法? 我不會使用任何其他腳本或工具,只是批處理。

在此先感謝

+2

問題標題,正文和標籤似乎是相互衝突的。標題指定了「bash」,我懷疑是正確的,因爲「batch」在問題主體中,並且標籤「批處理文件」和「窗口」被應用。我懷疑標題應該是這樣的:「使用批處理文件替換XML屬性值」。 – kbulgrien

+0

你是完全正確的。在過去的4年裏,我一直在使用Linux,但仍然很難交換 –

+0

純XML批處理腳本很難處理XML文件;我建議使用支持XML的語言,而不是將數據解釋爲「正常」文本,這是批量中唯一的可能性......無論如何,您迄今嘗試過什麼? – aschipfl

回答

2

這裏是一個純解決方案(我們稱之爲change-version.bat):

@echo off 
setlocal EnableExtensions DisableDelayedExpansion 

rem Define constants here: 
set "XML_FILE=.\sample.xml" 
set "TAG_NAME=tag" 
set "PAR_NAME=versionNumber" 
set "PAR_NEW_VAL="3.2.1"" 

for /F usebackq^ delims^=^ eol^= %%L in ("%XML_FILE%") do (
    set "LINE=%%L" 
    for /F "tokens=1,* delims=< eol=<" %%D in ("%%L") do (
     set "PRE=%%D" & set "LIN=%%E" 
     if not defined LIN (set "PRE=" & set "LIN=%%D") 
     setlocal EnableDelayedExpansion 
     for /F "tokens=1,* eol= " %%F in ("!LIN!") do (
      setlocal DisableDelayedExpansion 
      set "INT=%%F" & set "TAG=%%G" 
      setlocal EnableDelayedExpansion 
      if /I "!INT!"=="%TAG_NAME%" (
       for /F "tokens=1,* delims=> eol=>" %%T in ("!TAG!") do (
        setlocal DisableDelayedExpansion 
        set "TAG=%%T" & set "END=%%U" 
        call :SUB NEW TAG 
        setlocal EnableDelayedExpansion 
        echo(!PRE!^<%TAG_NAME%!NEW!^>!END! 
        endlocal 
        endlocal 
       ) 
      ) else (
       echo(!LINE! 
      ) 
      endlocal 
      endlocal 
     ) 
     endlocal 
    ) 
) 

endlocal 
exit /B 


:SUB var_new var_tag 
set "%~1=" 
:LOOP 
setlocal EnableDelayedExpansion 
for /F "tokens=1,* eol= " %%P in ("!%~2!") do (
    endlocal 
    for /F "tokens=1,* delims== eol==" %%V in ("%%P") do (
     if /I "%%V"=="%PAR_NAME%" (
      set "PAR=%%V=%PAR_NEW_VAL%" 
     ) else (
      set "PAR=%%V=%%W" 
     ) 
    ) 
    set "%~2=%%Q" 
    setlocal EnableDelayedExpansion 
) 
for /F delims^=^ eol^= %%S in ("!%~1! !PAR!") do (
    endlocal & set "%~1=%%S" 
) 
if defined %~2 goto :LOOP 
exit /B 

對於這項工作,對XML數據下面的條件必須滿足:

  • 的行持有標籤<tag>不包含任何其他XML標籤;
  • 包含參數versionNumber的標籤<tag>不得跨越多行;
  • 一個參數定義不能在=符號周圍包含空格;
  • (引用的)參數值不得包含<>字符;
  • 標記和參數名稱均不區分大小寫;

該腳本解析當前目錄中的XML文件sample.xml
將結果寫入文件,而不是到控制檯,重定向這樣的:

"change-version.bat" > "result.xml" 
1

隨着板載的東西,不是太容易。檢查Is there any sed like utility for cmd.exe

基本上你將創建進行置換(sed.vbs)短腳本:

Dim pat, pa tparts, rxp, inp 
pat = WScript.Arguments(0) 
patparts = Split(pat,"/") 
Set rxp = new RegExp 
rxp.Global = True 
rxp.Multiline = False 
rxp.Pattern = patparts(1) 
Do While Not WScript.StdIn.AtEndOfStream 
    inp = WScript.StdIn.ReadLine() 
    WScript.Echo rxp.Replace(inp, patparts(2)) 
Loop 

最後執行命令從Windows批量替換:

csript //NoLogo sed.vbs s/2.0.3/2.0.4/ <yourFile.xml> newFile.xml 
0

有是解決這個問題的幾種不同方法,但最有效的方法是通過VBScript/JScript編程語言的正則表達式替換功能,最簡單的方法是使用Batch-JScript混合腳本:

@set @a=0 /* 
@cscript //nologo //E:JScript "%~F0" <input.xml> output.xml 
@goto :EOF */ 


// JScript code section 

WScript.Stdout.Write(WScript.Stdin.ReadAll().replace(/versionNumber=[^ ]+ /g,"versionNumber=\"X.Y.Z\" ")); 

保存此文件的擴展名爲.BAT。