在标记之前使用批处理文件在XML中添加一行

时间:2016-05-26 23:43:41

标签: regex xml windows batch-file

我有一个

类型的XML文件
....
<sometag>
<tag attr_name1="long filename1" />
<tag attr_name2="long filename2" />
....
</sometag>
....

</sometag>之前我想添加<tag attr_name="long filename" />到目前为止我的Windows批处理脚本中的代码是:

@echo off
setlocal enableDelayedExpansion
set "newValue=^<tag attr_name="long filename" /^>
set newline=^& echo.
type "File.xml"|replace "(</tag>)" "!newValue!$1" >dupFile.xml
move /y "dupFile.xml" "File.xml"

我得到&#34; Path not found - </tag>&#34;和File.xml包含&#34;没有替换文件&#34;。我知道从批处理文件编辑XML不是最好的做法,但不幸的是不能使用第三方可执行文件。有人可以帮我解决我出错的地方吗?

我还检查了the thread使用批处理文件更改XML中标签之间的数据,当我在那里使用建议的代码并改变我的要求时,我得到了上述错误。

1 个答案:

答案 0 :(得分:4)

如果</sometag>在XML中只出现一次,并且如果它之前没有在层次结构中插入新的<tag>节点,那么您可以通过以下方式遍历XML文件for /F循环,检查每行是否包含</sometag>。找到后,只需在回显匹配的行之前回显新的<tag>

@echo off
setlocal

>"newfile.xml" (
    for /f "usebackq delims=" %%I in ("xmlfile.xml") do (
        set "line=%%I"
        setlocal enabledelayedexpansion
        if not "!line!"=="!line:/sometag=!" (
            echo ^<tag attr_name="long filename" /^>
        )
        endlocal
        echo(%%I
    )
)

type "newfile.xml"

但实际上,假设您的XML完全有效,最优雅的解决方案是将XML解析为结构化数据,而不是作为复杂的文本进行破解和删除。这样,你的代码是否被美化,缩小,丑化或其他什么都无关紧要。无论缩进和换行如何,解析器仍然可以理解它。您可以使用已经内置到Windows中的语言(VBScript,JScript,PowerShell,C#)执行此操作,然后列表继续。批处理可能是您熟悉的唯一语言,但它不是Windows基本安装中唯一可用的语言。这是一个快速而又脏的批处理+ PowerShell混合脚本来演示。 (以.bat扩展名保存。)

<# : batch portion (within a multiline PowerShell comment)
@echo off & setlocal

set "infile=test.xml"
set "parentNode=sometag"
set "newTag=tag"
set "newAttr=attr_name"
set "attrVal=long filename"
set "outfile=new.xml"

powershell -noprofile -noninteractive "iex (${%~f0} | out-string)"
type "%outfile%"

goto :EOF

: end batch (multiline comment) / begin PowerShell hybrid code #>

[xml]$xml = gc $env:infile
$parent = $xml.documentElement.selectSingleNode("//$env:parentNode")
$new = $xml.createElement($env:newTag)
[void]$new.setAttribute($env:newAttr, $env:attrVal)
[void]$parent.appendChild($new)
$xml.save($env:outfile)