2016-04-28 87 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。