我需要从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
。
答案 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
被视为令牌ghij
,hello
,delims
和/:
。默认情况下,它设置为逗号和空格。
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 %%b
和set %%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%