0

我是编写批处理脚本的初学者,非常感谢您对此的帮助。

下面是 xml,我需要将标志为“on”的所有名称提取到 txt 文件中。还有其他几个类别标签实例。

<Head>
   <Category
      name="RIVERTD"
      flag="on"
      location="SG002">
    </Category>
   <Category
      name="BRETRED"
      flag="on"
      location="IT213">
    </Category>
   <Category
      name="AMERAND"
      flag="off"
      location="US212">
   </Category>
</Head>

所以,我正在寻找的输出如下

RIVERTD
BRETRED

我尝试使用下面的代码

@echo off
setlocal disableDelayedExpansion
set input="CP.xml"
set output="Names.txt"

if exist %output% del %output%
for /f "delims=" %%A in ('findstr /n /c:"name=" %input%') do (
  set "ln=%%A"
  setlocal enableDelayedExpansion
  call :parseLine
  endlocal
)
type %output%
exit /b

:parseLine
set "ln2=!ln:*name=!"
if "!ln2!"=="!ln!" exit /b
for /f tokens^=2^ delims^=^" %%B in ("!ln2!") do (
  setlocal disableDelayedExpansion
  >>%output% echo(%%B
  endlocal
)
set "ln=!ln2!"
goto :parseLine

这给了我结果

RIVERTD
BRETRED
AMERAND

但是,此代码不会根据标志过滤名称。我是初学者。请帮助添加基于标志的过滤器。非常感谢。

4

3 回答 3

3

这是xpath.bat -small 脚本,它允许您通过 xpath 表达式获取 xml 值,而无需使用外部二进制文件:

call xpath.bat "CP.xml" "//Category[0]/@name"
call xpath.bat "CP.xml" "//Category[1]/@name"
于 2017-02-07T14:52:15.510 回答
1

这应该为你做。

@echo off
setlocal enabledelayedexpansion

set "Name="
set "Flag="
set "Output=Names.txt"

for /f "usebackq delims=" %%L in (`type "CP.xml"`) do (
    for /f "usebackq tokens=1,2* delims=    =<> " %%A in ('%%L') do (
        if /i "%%~A"=="name" set "Name=%%~B"
        if /i "%%~A"=="flag" set "Flag=%%~B"
        if /i "%%~A"=="/category" (
            if /i "!Flag!"=="on" echo.!Name!>>%Output%
            set "Name="
            set "Flag="
        )
    )
)

endlocal
pause
于 2012-12-17T01:21:28.063 回答
1

这个问题可以用一个非常有趣的技巧来解决!:

@echo off
setlocal EnableDelayedExpansion
(for /F "tokens=1,2 delims== " %%a in (CP.xml) do (
   if "%%~b" neq "" set %%a=%%~b
   if /I "!flag!" equ "on" echo !name!& set flag=
)) > Names.txt

编辑添加了一些解释

该文件有几行,但 OP 会查找具有赋值形式的行,如下所示:

  name="RIVERTD"
  flag="on"

  name="BRETRED"
  flag="on"

  name="AMERAND"
  flag="off"

我的程序不检查任何名称,而是执行等号后带有值的任何行作为赋值。这样,当我的程序处理前几行时,结果相当于执行了以下命令:

  set name="RIVERTD"
  set flag="on"

  set name="BRETRED"
  set flag="on"

  set name="AMERAND"
  set flag="off"

之后,只需检查 FLAG 变量的值是否为“on”;如果是这样,则 NAME 变量具有目标值,因为它是在前一行中分配的。

安东尼奥

于 2012-12-17T02:22:19.343 回答