Bob Vandevliet
Bob Vandevliet

Reputation: 213

Extract multiple values from one line string with batch file

I'm trying to extract every value for FileRef from a string I've already extracted out of a file. Unfortunately, the string is one line which makes it more difficult to use for /f "tokens=*".

The string is:

"<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>"

How to get every value for FileRef inserted into a variable in the following format?:

A1-FS.elt?A1-MS.elt?Product\Product-v1\Product-v1-MD.elt?Product\Product-v2\Product-v2-MD.elt?RunnerPart_Assembly#1.elt

I mean, then I could loop trough them using for /f "delims=?" right?

Or is there a way to convert each ? in the above example to a 'new line' within one string, or maybe even better ideas to loop trough each FileRef-value?

Many thanks!

Upvotes: 0

Views: 1026

Answers (2)

aschipfl
aschipfl

Reputation: 34899

Squashman is right in his comment, use a language that is capable of handling XML data natively.

Anyway, if you insist on using pure Windows batch scripting, you could assemble a new string with ? symbols as separator like in the following script:

@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

Toggling delayed expansion is done in order not to have trouble with ! symbols.

Better than collecting all values in a single variable is to just loop through them in my opinion.

Upvotes: 3

Squashman
Squashman

Reputation: 14290

This is one other way to brute force this. This code will put each FileRef into its own variable and sequence the variable name up.

@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

When executed it will output this.

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 . . .    

If you don't want the data assigned into their own individual variables you can just use the %%G meta-variable directly inside the FOR command.

Upvotes: 1

Related Questions