Windows批处理从XML读取路径

时间:2016-12-17 07:29:11

标签: xml batch-file

我需要从XML文件中的属性读取路径,但空格让我遇到问题。

@echo off

:: Write a VBS file for getting modfolder from gameSettings.xml
> "%TEMP%\moddir.vbs" (
echo.Dim oXml: Set oXml = CreateObject^("Microsoft.XMLDOM"^)
echo.oXml.Load WScript.Arguments.Item^(0^)
echo.Dim oDoc: Set oDoc = oXml.documentElement
echo.
echo.For Each node In oDoc.childNodes
echo.   If ^(node.nodeName = "modsDirectoryOverride"^) And ^(node.getAttribute^("active"^) = "true"^) Then
echo.       WScript.Echo node.getAttribute^("directory"^)
echo.   End If
echo.Next
echo.Set oXml = Nothing
)

:: Setting Mod directory
SETLOCAL
for /f %%i in ('cscript %TEMP%\moddir.vbs "%UserDocs%\My Games\FarmingSimulator2017\gameSettings.xml" //Nologo') do set "moddir=%%i"

echo moddir = %moddir%

XML文件中的行是:

<?xml version="1.0" encoding="utf-8" standalone="no" ?>
<gameSettings revision="11">
<modsDirectoryOverride active="true" directory="D:\games\Farming Simulator\Farming simulator 17\Mods"/>
</gameSettings>

变量moddir设置为D:\games\Farming,但它应为D:\games\Farming Simulator\Farming simulator 17\Mods

2 个答案:

答案 0 :(得分:1)

@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "filename1=%sourcedir%\q41196420.txt"
FOR /f "usebackqtokens=1,3delims=<=>/" %%a IN ("%filename1%") DO (
 IF "%%~a"=="modsDirectoryOverride active" ECHO dir=%%~b
)

GOTO :EOF

您需要更改sourcedir的设置以适合您的具体情况。

我使用了一个名为q41196420.txt的文件,其中包含我的测试数据。

这是一种简单的方法 - 只需选择合适的令牌和分隔符,然后使用if过滤

最好提供待解决的问题,而不是单独解决问题。

@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "filename1=%sourcedir%\q41196420.txt"
FOR /f "usebackqtokens=1-7delims=<=>/" %%a IN ("%filename1%") DO (
ECHO + %%a + %%b + %%c + %%d + %%e + %%f + %%g +
REM note content of "%%x" - %%~x = %%x minus quotes at either end
REM we may need to tokenise "%%a" using spaces as delimiters
 FOR /f "tokens=1*delims= " %%m IN ("%%a") DO (
 REM %%a..%%g, %%m and %%n are in-context
  ECHO + %%m + %%n
  REM same formula for "%%b"
  FOR /f "tokens=1*delims= " %%p IN ("%%b") DO (
  REM %%a..%%g, %%m and %%n are in-context
   ECHO + %%p + %%q
   ECHO + %%a + %%b + %%c + %%d + %%e + %%f + %%g + %%m + %%n + %%p + %%q +
   REM So, select your parts. if /i=case-insensitive since I abhor CaMeLcAsE
   IF /i "%%~m"=="modsdirectoryoverride" IF /i "%%n"=="active" IF /i "%%~p"=="true" ECHO.&ECHO ***Directory=%%~c*** or ***Directory=%%c*** as you wish
  )
 )
 REM %%a..%%g are in-context, %%m and %%n are not
 ECHO.
)

GOTO :EOF

如果您阅读文档(提示中的for /? |more),那么您可能会被迷惑。

上面的代码显示了如何批量拆解行,重要的是条件选择目录名。

采取任何文字。这可能是文件中的一系列行之一,从命令甚至变量输出的一系列行。

首先,使用delims指定要使用的分隔符。该行被视为由[sequence of delimiter [s]

分隔的一系列标记

如果abc/123:ghij/:/hello设置为abc,则123被视为令牌ghijhellodelims/: 。默认情况下,它设置为逗号和空格。

tokens关键字将所选字符串分配给metavariables(循环控制变量+)。如果元变量为%%a,则最低选定标记将分配给%%a,下一个最低标记将分配给%%b,依此类推。 *是一个特殊的,意思是“选择最高标记后的所有内容,包括分隔符”。 tokens默认为1

因此,将tokens=1,3应用于带有元变量abc/123:ghij/:/hello的上述标记%%a将设置%%a=abc(第1个)和%%b=ghij(第3个)。

除此之外,您可能需要usebackq来允许读取引号中的文件名(如果全名包含空格则需要);如果省略usebackq,将按字面使用带引号的字符串。

答案 1 :(得分:1)

我为您提供了一个更简单的纯文件批处理文件,但缺点是它只适用于您显示的xml文件格式。

findstr命令可以从具有给定字符串的文件中提取行。例如,findstr "modsDirectoryOverride" "gameSettings.xml"命令显示以下行:

<modsDirectoryOverride active="true" directory="D:\games\Farming Simulator\Farming simulator 17\Mods"/>

如果我们根据for /F命令将此行分开,并将该空格用作默认分隔符,并包含以下选项:for /F "tokens=1,2*" %%a in ('previous line') do ...,您会发现for参数包含这些值:

%%a have <modsDirectoryOverride
%%b have active="true"
%%c have directory="D:\games\Farming Simulator\Farming simulator 17\Mods"/>

然后,我们可以执行set %%bset %%c命令,这些命令等同于这些命令:

set active="true"
set directory="D:\games\Farming Simulator\Farming simulator 17\Mods"/>

之后,您只需要测试%active%是否"true"来显示目录,就是这样! ;) 唯一的细节是%directory%的值以引号开头并以"/>结尾,因此必须从输出中删除这些字符:

@echo off
setlocal

for /F "tokens=1,2*" %%a in ('findstr "modsDirectoryOverride" "gameSettings.xml"') do (
   set %%b
   set %%c
)
if %active% equ "true" echo %directory:~1,-3%