从批处理程序中读取XML文件

时间:2018-02-17 16:44:57

标签: xml batch-file

早上好,

我一直在网上搜索,我可以找到任何可以解决我想要做的事情。我有这个XML文件。

<?xml version="1.0"?>
<menu>
  <header>
    <listname>Nintendo GameCube</listname>
    <lastlistupdate>09/26/2017</lastlistupdate>
    <listversion>SupraKarma1.1</listversion>
  </header>
  <game name="007 - Agent Under Fire (USA)" index="true" image="0">
    <description>007: Agent Under Fire (USA)</description>
    <cloneof />
    <crc />
    <manufacturer>EA Games</manufacturer>
    <year>2002</year>
    <genre>Action</genre>
    <rating>ESRB - T (Teen)</rating>
    <enabled>Yes</enabled>
  </game>
  <game name="007 - Everything or Nothing (USA)" index="" image="">
    <description>007: Everything or Nothing (USA)</description>
    <cloneof />
    <crc />
    <manufacturer>EA Games</manufacturer>
    <year>2004</year>
    <genre>Action</genre>
    <rating>ESRB - T (Teen)</rating>
    <enabled>Yes</enabled>
  </game>
</menu>

我需要从批处理文件中读取它。我以为我可以使用vb脚本但是由于原因,我不会进入我不能这样我回到批处理程序。我想让它搜索一个像“007 - Everything or Nothing(USA)”这样的文件,让它将游戏-ESRB-T(青少年)的评级恢复为变量。

有人可以帮帮我吗?

非常感谢!

3 个答案:

答案 0 :(得分:0)

我还没有对它进行过测试,但你可以使用xpath.bat from GitHUB来检索带有这样的XPath的节点:

//game[contains(@name,"007 - Everything or Nothing (USA)")]

因此,如果您想从批处理文件中调用它,请使用类似

的内容
call xpath.bat [parameters]

答案 1 :(得分:0)

我建议你从批处理文件中利用PowerShell来完成这类任务:

@Echo Off
Set "name=007 - Everything or Nothing (USA)"
Set "file=filename.xml"
Set "want=rating"
Set "variable="
For /F "Delims=" %%A In ('PowerShell -C "$xml=[xml](GC '%file%');"^
 "$xml.menu.game | ? {$_.name -eq '%name:'=''%'} |"^
 "Select -ExpandProperty %want%"') Do Set "variable=%%A"
If Defined variable Echo %variable%
Pause

答案 2 :(得分:0)

以下是此任务的纯Windows批处理文件解决方案:

@echo off
set "GameNameFound="
for /F "tokens=2,3 delims==<>" %%I in ('type "C:\Temp\Test.xml" ^| %SystemRoot%\System32\findstr.exe /L /C:"007 - Everything or Nothing (USA)" /C:"<rating>" 2^>nul') do (
    if "%%I" == "game name" (
        set "GameNameFound=1"
    ) else if defined GameNameFound (
        set "Rating=%%J"
        set "GameNameFound="
        goto HaveRating
    )
)
set "GameNameFound="
echo Could not find rating for game "007 - Everything or Nothing (USA)".
goto :EOF

:HaveRating
echo Rating for game "007 - Everything or Nothing (USA)" is: %Rating%

命令 FOR 在一个单独的命令进程中执行,该进程在命令行的后台以cmd.exe /C开头:

type "C:\Temp\Test.xml" | C:\Windows\System32\findstr.exe /L /C:"007 - Everything or Nothing (USA)" /C:"<rating>" 2>nul

此命令行输出命令 TYPE 文件C:\Temp\Test.xml的内容以处理 STDOUT ,该文件被|重定向到输入句柄<命令 FINDSTR 的强> STDIN ,对字符串007 - Everything or Nothing (USA)<rating>进行字面搜索和区分大小写。 FINDSTR 输出包含第一个或第二个字符串的所有行。因此,对于您的示例,输出行:

    <rating>ESRB - T (Teen)</rating>
  <game name="007 - Everything or Nothing (USA)" index="" image="">
    <rating>ESRB - T (Teen)</rating>

这些行由命令 FOR 捕获,现在逐行处理。

由于delims==<>,每条线被分成多个子串(标记),使用等号和尖括号作为字符串分隔符。 tokens=2,3告诉 FOR ,处理行的第二个子字符串应该分配给指定的循环变量I,第三个子字符串应该分配给下一个循环变量J根据ASCII table。所有其他子字符串(例如空格/制表符左侧的开放标记(第一个子字符串)和剩余的每行都不感兴趣。

忽略第一行<rating>ESRB - T (Teen)</rating>,因为尚未定义环境变量GameNameFound

第二个已处理的行是 FINDSTR 找到的游戏名称的行,其中起始标记game和属性name被分配给循环变量I与之间的空间。因此,现在使用任何值定义环境变量GameNameFound。将哪个值分配给环境变量无关紧要。

第三行应该是rating感兴趣的行,它的第三个子字符串分配给循环变量J是感兴趣的评级值。因此,此字符串值将分配给环境变量Rating,并退出 FOR 循环,并跳转到标签HaveRating以进行进一步处理。

要了解使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完全阅读为每个命令显示的所有帮助页面。

  • echo /?
  • findstr /?
  • for /?
  • goto /?
  • if /?
  • set /?
  • type /?

另请阅读Microsoft有关Using Command Redirection Operators的文章,了解|2>nul的说明。重定向操作符|>必须在 FOR 命令行上使用插入符^进行转义,以便在Windows命令解释程序处理此命令时将其解释为文字字符执行命令 FOR 之前的行,它在后台启动的单独命令进程中执行嵌入式命令行。