使用批处理提取XML标记值(基于标记)

时间:2012-12-16 15:26:26

标签: xml batch-file xml-parsing

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

下面是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

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

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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变量是否具有值&#34; on&#34 ;;如果是这样,那么NAME变量具有目标值,因为它是在前一行中分配的。

安东尼奥

答案 2 :(得分:1)

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

call xpath.bat "CP.xml" "//Category[0]/@name"
call xpath.bat "CP.xml" "//Category[1]/@name"