我有一个XML文件,其方式如下:
<pools>
<pool>aaa</pool>
<pool>bbb</pool>
<pool>ccc</pool>
<pool>ddd</pool>
<pool>eee</pool>
</pools>
我想解析这些标签,以便将它们分配给变量
Pool1 =aaa
Pool2 = bbb
依此类推
我尝试了以下代码:
echo off
set /a x=0
SETLOCAL enableextensions enabledelayedexpansion
for /f "tokens=2 delims=<>" %%a in ('find /i "<pool>" ^< "pool_info.xml"') do (
set /a "x+=1"
call ECHO pool%%x%%=%%a
)
它只是正确打印它们。我尝试了set
命令来分配它们,但它不起作用。
我经历了许多堆栈溢出问题,但无法找到任何符合我要求的解决方案。如果有人能帮我。
PS:这里的<pool>
标签计数是5,但是,计数可以更改,因此我希望它灵活。
该任务可以通过以下方式完成:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Delete all environment variables of which name starts with Pool.
for /F "delims==" %%I in ('set Pool 2^>nul') do set "%%I="
set "PoolCount=0"
for /F "tokens=2 delims=<> " %%I in ('%SystemRoot%System32findstr.exe /I /L /C:"<pool>" "pool_info.xml"') do (
set /A PoolCount+=1
call set "Pool%%PoolCount%%=%%I"
)
rem Output all environment variables of which name starts with Pool.
set Pool
endlocal
注意:分隔符是两个尖括号,一个水平制表符和一个普通空格字符。请确保批处理文件正好包含按该顺序delims=
后的这四个字符。
需要水平制表符和普通空格作为分隔符,以使具有独立于pool
元素行上的前导空格/制表符的工作解决方案。
错误的标记分别缺少分隔符制表符/空格,导致在获取元素名称pool
输出而不是 XML 元素的值时发布有问题的代码pool
。
在这种情况下,无需使用延迟环境变量扩展。
但是,使用call
强制对命令行进行第二次解析
call set "Pool%%PoolCount%%=%%I"
在解析整个命令块期间已修改为
call set "Pool%PoolCount%=%I"
在执行之前,与使用以下代码中使用的延迟扩展相比,set
速度较慢。
@echo off
setlocal EnableExtensions EnableDelayedExpansion
rem Delete all environment variables of which name starts with Pool.
for /F "delims==" %%I in ('set Pool 2^>nul') do set "%%I="
set "PoolCount=0"
for /F "tokens=2 delims=<> " %%I in ('%SystemRoot%System32findstr.exe /I /L /C:"<pool>" "pool_info.xml"') do (
set /A PoolCount+=1
set "Pool!PoolCount!=%%I"
)
rem Output all environment variables of which name starts with Pool.
set Pool
endlocal
原因由 jeb 在 DosTips 论坛帖子中解释 打电话给我,或者最好避免打电话。Windows 命令处理器在当前目录的批处理文件中使用call set "Pool%%PoolCount%%=%%I"
搜索,然后在环境变量PATH
的所有目录中使用 搜索与通配符模式set.*
匹配的文件。如果确实在其中一个目录中找到类似set.txt
的文件,它会在该目录中搜索set.COM
、set.EXE
、set.BAT
、set.CMD
、...根据环境变量PATHEXT
的文件扩展名列表。如果确实有一个可执行文件或脚本被cmd.exe
在当前目录或其他文件扩展名为PATHEXT
的PATH
目录中找到文件名set
,它将执行可执行文件/脚本而不是运行内部命令SET。
因此,使用延迟扩展解决方案肯定更好,因为它更快,更安全。
缺点是,具有一个或多个!
的pool
值在启用延迟扩展的情况下无法正确处理。因此,cmd.exe
再次证明了Windows命令处理器是为执行命令和可执行文件而设计的,而不是用于处理文本文件中的数据。
要了解使用的命令及其工作原理,请打开命令提示符窗口,在其中执行以下命令,然后完整而仔细地阅读每个命令的显示帮助页面。
call /?
......用于在执行set
之前对命令行进行双重解析。echo /?
endlocal /?
findstr /?
for /?
rem /?
set /?
setlocal /?
阅读有关使用命令重定向运算符的Microsoft文档,了解2>nul
的说明。当 Windows 命令解释器在执行命令 FOR 之前处理此命令行时,重定向运算符>
必须使用插入符号^
FOR 进行转义,以便在执行命令FOR之前使用此命令行,该命令使用在后台启动的单独命令进程执行嵌入式set
命令行,%ComSpec% /c
和'
中的命令行追加为附加参数。
...
set /a "x+=1"
call SET pool%%x%%=%%a
)
SET pool
第一个set
将%%a
中的值分配给变量pool?
第二个set
显示名称以pool
开头的所有当前设置的环境变量。
setx
是一个命令,旨在记录变量赋值以供将来的cmd
实例使用。这是一个完全不同的问题,应该作为一个单独的问题提出,但是有很多关于setx
的SO项目,因此(再次)将其作为单独的问题提出可能会作为重复问题关闭。最好使用search
设施进行setx
。