我正在尝试从我已经从文件中提取的字符串中提取FileRef
的每个值。不幸的是,字符串是一行,这使得使用for /f "tokens=*"
更加困难。
字符串是:
"<Cim:TrnTable_list><Cim:TrnTable Id="Root"><Cim:TrnElem Ref="3" FileRef="A1-FS.elt"/><Cim:TrnElem Ref="4" FileRef="A1-MS.elt"/><Cim:TrnElem Ref="9" FileRef="Product\Product-v1\Product-v1-MD.elt"/><Cim:TrnElem Ref="11" FileRef="Product\Product-v2\Product-v2-MD.elt"/><Cim:TrnElem Ref="12" FileRef="RunnerPart_Assembly#1.elt"/></Cim:TrnTable></Cim:TrnTable_list>"
如何将FileRef
的每个值插入到以下格式的变量中?:
A1-FS.elt?A1-MS.elt?Product\Product-v1\Product-v1-MD.elt?Product\Product-v2\Product-v2-MD.elt?RunnerPart_Assembly#1.elt
我的意思是,然后我可以使用for /f "delims=?"
对吗?
或者有没有办法将上面示例中的每个?
转换为一个字符串中的“新行”,或者甚至更好的方法来循环每个FileRef
- 值?
非常感谢!
答案 0 :(得分:3)
Squashman在他的comment中是正确的,使用能够原生处理XML数据的语言。
无论如何,如果你坚持使用纯Windows批处理脚本,你可以组装一个带有?
符号的新字符串作为分隔符,如下面的脚本所示:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_FILE=%~dpn0.txt" & rem // (path to file containing the line of text)
(set ^"_LF=^
%= empty line =%
^") & rem // (this constitutes a new-line character)
rem // Initialise collection variable:
set "COLL=?"
rem // Read line from file:
for /F "usebackq delims=" %%L in ("%_FILE%") do (
set "LINE=%%~L"
setlocal EnableDelayedExpansion
rem // Replace `><` by `>` + line-break + `<`:
set ^"LINE=!LINE:^>^<=^>^%_LF%%_LF%^<!^"
rem // Read one tag enclosed within `<` and `>`:
for /F "delims=" %%I in ("!LINE!") do (
endlocal
set "ITEM=%%I"
rem // Extract string between ` FileRef` and `/>`:
setlocal EnableDelayedExpansion
set "ITEM=!ITEM:* FileRef=!"
set "ITEM=!ITEM:/>=!"
rem // Check for `=`-sign after `FileRef`:
if "!ITEM:~,1!"=="=" (
rem // Remove leading `=` and surrounding `""`:
for /F "delims=| eol=|" %%F in ("!ITEM:~1!") do (
endlocal
set "NAME=%%~F"
rem // Assemble return string using `?` as separator:
setlocal EnableDelayedExpansion
for /F "delims=| eol=|" %%J in ("!COLL!!NAME!?") do (
endlocal
set "COLL=%%J"
setlocal EnableDelayedExpansion
)
)
)
)
endlocal
)
rem // Return collection variable:
setlocal EnableDelayedExpansion
echo(!COLL:~1,-1!
endlocal
endlocal
exit /B
切换delayed expansion是为了避免!
符号出现问题。
比收集单个变量中的所有值更好的是在我看来只是循环遍历它们。
答案 1 :(得分:1)
这是暴力破坏的另一种方式。此代码将每个FileRef放入其自己的变量中,并对变量名称进行排序。
@echo off
FOR /F "delims=" %%G IN (line.txt) do set "line=%%G"
set i=0
:loop
set /a i+=1
set "line=%line:*FileRef=%"
FOR /F "tokens=1* delims==/" %%G IN ("%line%") DO (
set "var%i%=%%~G"
set "line=%%H"
)
echo "%line%"|find /I "fileref" >nul 2>&1 &&GOTO loop
set var
pause
执行时会输出。
C:\BatchFiles\SO\XML>bruteforce.bat
var1=A1-FS.elt
var2=A1-MS.elt
var3=Product\Product-v1\Product-v1-MD.elt
var4=Product\Product-v2\Product-v2-MD.elt
var5=RunnerPart_Assembly#1.elt
Press any key to continue . . .
如果您不希望将数据分配到各自的变量中,则可以直接在%%G
命令中使用FOR
元变量。