微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在解析相似命名的 XML 元素时为具有动态名称的环境变量赋值?

如何解决如何在解析相似命名的 XML 元素时为具有动态名称的环境变量赋值?

我有以下方式的 XML 文件

<pools>
    <pool>aaa</pool>
    <pool>bbb</pool>
    <pool>ccc</pool>
    <pool>ddd</pool>
    <pool>eee</pool>
</pools>

我想以这样的方式解析这些标签,以便将它们分配给变量

池 1 = 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 命令来分配它们,但它不起作用。

我遇到了许多 Stack Overflow 问题,但找不到符合我要求的任何解决方案。如果有人可以帮助我。

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%\System32\findstr.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"

与使用 delayed expansion 相比,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%\System32\findstr.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

原因由 DosTips 论坛帖子 jeb 中的 CALL me,or better avoid call 解释。 Windows 命令处理器使用 call set "Pool%%PoolCount%%=%%I" 在当前目录的批处理文件中搜索,然后在环境变量 PATH 的所有目录中搜索匹配通配符模式 set.* 的文件。如果确实在其中一个目录中找到了类似 set.txt 的文件,它会在该目录中搜索下一个 set.COMset.EXEset.BATset.CMD, ...根据环境变量 PATHEXT 的文件扩展名列表。如果 cmd.exe 在当前目录或 set 的其他目录中确实找到了文件名为 PATH 的可执行文件或脚本,文件扩展名为 PATHEXT,它会执行可执行文件/脚本,而不是运行内部命令 SET

因此,使用延迟扩展方案肯定更好,因为它更快更安全。

缺点是带有一个或多个 pool! 值在启用延迟扩展的情况下无法正确处理。因此,cmd.exe 再次证明了自己的 Windows 命令处理器是为执行命令和可执行文件而设计的,而不是用于处理文本文件中的数据。

要了解使用的命令及其工作原理,请打开 command prompt 窗口,在那里执行以下命令,并仔细阅读为每个命令显示的所有帮助页面。

  • call /? ... 用于在执行 set 之前对命令行进行双重解析。
  • echo /?
  • endlocal /?
  • findstr /?
  • for /?
  • rem /?
  • set /?
  • setlocal /?

阅读有关 Using command redirection operators 的 Microsoft 文档以了解 2>nul。重定向运算符 > 必须在 FOR 命令行上用脱字符符 ^ 转义,以便在 Windows 命令解释器在执行命令 之前处理此命令行时被解释为文字字符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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。