批处理文件:读取 XML 时会删除 CDATA 中的感叹号 (!)



目前,我有一个执行以下操作的脚本:

  1. 在特定文件夹中查找
  2. 解压缩所有 *.zip 文件
  3. 读取具有四列(旧名称,旧名称,新ID,新名称)的特定CSV文件
  4. 递归方式查找文件夹中的所有 *.xml 文件(示例.xml)
  5. 循环浏览*.xml文件,创建副本(原始bak和潜在的修改bak)
  6. 将旧名称替换为新名称,新名称
  7. 如果修改,则写入XML,删除原始文件,将bak移动到原始文件。

最后一步是我的问题所在。目前,当批处理文件读取 XML 文件时,它会丢失感叹号。导出前,示例行为: <url><![CDATA[pdf/Post-Rec_Job Model Training.pdf]]></url> 结果为 <url><[CDATA[pdf/Post-Rec_Job Model Training.pdf]]></url>

如何保持感叹号?

必须确保

在展开可能包含!文本的 FOR 变量时不启用延迟扩展。您可以修改 :replaceCourseInfo 例程,以在循环中打开和关闭延迟扩展,而不是在例程顶部打开它。

我同意 foxidrive,我不明白修改后的变量是如何使用的,所以我把它去掉了。

:replaceCourseInfo
    @echo off
    setlocal
    set INTEXTFILE=%~1
    set OUTTEXTFILE=%~1
    copy %INTEXTFILE% %INTEXTFILE%.bak
    copy %INTEXTFILE% %INTEXTFILE%.original.bak
    set BAKFILE=%~1.bak
    if exist "%~1.bak" del /F /Q "%~1.bak"
    REM Walk through XML Lines
    REM @todo Need to prevent losing ! in [!CDATA[
    for /F "delims=" %%U in (%~1) do (
        set LINE=%%U
        setlocal enabledelayedexpansion
        if not "!LINE!" == "!LINE:%~2=!" (
            set LINE=!LINE:%~2=%~3!
        )
        >> "%BAKFILE%" echo.!LINE!
        endlocal
    )
    REM If modified, delete original, copy modified bak as new original
    if NOT "%~2"=="%~3" (
        del /F /Q %~1
        copy %BAKFILE% %~1
    )
goto:eof

我曾经使用 FOR/F 循环来修改文本文件,但获得所需结果通常很复杂。我编写了foxidrive所说的REPL.BAT脚本,现在我几乎总是使用REPL.BAT而不是FOR/F循环来修改文件。REPL.BAT更简单,更快捷。

问题是delayed expansion - 可以解决。

您正在使用下面的代码 - 显然没有使用modified变量。

如果字符串中存在%~2,您的代码似乎只是简单地用%~3替换%~2,这可以通过 dbenham 或 SEDVBS search and replace featureREPL.BAT来完成。

REM Walk through XML Lines
REM @todo Need to prevent losing ! in [!CDATA[
for /F "delims=" %%U in (%~1) do (
    set LINE=%%U
    if not "!LINE!" == "!LINE:%~2=!" (
        set LINE=!LINE:%~2=%~3!
        set modified=!string:%~2=%~3!
    )
    >> "%BAKFILE%" echo. LINE!
)

以下是替换上述代码的REPL.BAT解决方法:

type "%~1" | REPL "%~2" "%~3" L >> "%BAKFILE%"

最新更新