Although Windows batch can be kind of lame handling xml, this (quite simple) case could be solved using a (quite simple) script providing additional preliminary assumptions on structure of parsed line(s).
However, the following solution lays emphasis on (as far as possible) universal approach with no premises on position of Client= attribute inside the containing tag, or its unicity (singularity) inside a line, or number of preceding " double quotes etc. etc.:
@ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
for /F "delims=" %%G in ('
findstr /i /r "\<Client=" "D:\bat\SO\files\q44533501_input.xml"
') do (
rem ECHO=merely debugging output
ECHO %%G
set "_line=%%~G"
call :lineFound
)
goto :eof
:lineFound
rem remove cmd-poisonous characters `<` and `>` (replace them with spaces)
set "_line=%_line:<= %"
set "_line=%_line:>= %"
set "_takeNextItem="
rem parse
for %%g in ( %_line% ) do (
if defined _takeNextItem (
set "_takeNextItem="
set "_client=%%~g"
call :clientSet
) else (
if /I "%%~g" == "Client" set "_takeNextItem=%%~g"
)
)
goto :eof
:clientSet
rem ECHO=merely debugging output;
rem handle %_client% variable in desired manner instead
ECHO(%_client%
goto :eof
Of course, you could use sfk find "C:\Env\Test\test.xml" "Client=" command instead of my findstr /i /r "\<Client=" "D:\bat\SO\files\q44533501_input.xml" at the 4th line.
Sample output (includes debugging ECHO %%G to show possible variability of input xml file):
==> D:\bat\SO\q44533501.bat
<Org Updated="date" Owner="Test" Version="2/1/3/4" Database="Test" Client="Name">
Name
<Org Updated="date" Database="Test" Client="Name2" Owner="Test" Version="2/1/3/4">
Name2
<Org Updated="yesterday" Client="Name3"></Org><Org Client="Name4" Updated="today">
Name3
Name4
==>
Edit. To explain the :lineFound section, let's take look at FOR command (it is mostly used to process files, but you can also process text strings):
Conditionally perform a command on several files.
Syntax
FOR %%parameter IN (set) DO command
Key
set : A set of one or more files, separated by any standard delimiter.
Wildcards can be used.
command : The command to carry out, including any command-line parameters.
%%parameter : A replaceable parameter: e.g. in a batch file use %%G
(on the command line %G)
and utilise the fact that a xml line we want to parse contains just standard delimiters mentioned above in set description, see Delimiters:
Delimiters separate one parameter from the next - they split the
command line up into words.
Parameters are most often separated by spaces, but any of the
following are also valid delimiters:
- Comma (,)
- Semicolon (;)
- Equals (=)
- Space ( )
- Tab ( )
Some example might help: for %g in ( %_line% ) do … loop processes, item by item, the _line variable after splitting it using standard delimiters as item separators. In principle, we obtain a sequence where each attribute name is followed by attribute value (but tag name as the first item):
==> for %g in ( %_line% ) do @echo %g
Org
Updated
"date"
Database
"Test"
Client
"Name2"
Owner
"Test"
Version
"2/1/3/4"
==>
Note that _line variable is hard-coded, for this particular sample case, as
==> set "_line=<Org Updated="date" Database="Test" Client="Name2" Owner="Test" Version="2/1/3/4">"
==> set "_line=%_line:<= %"
==> set "_line=%_line:>= %"
==> set _line
_line= Org Updated="date" Database="Test" Client="Name2" Owner="Test" Version="2/1/3/4"
sfkcommand is only doing exactly the same as the built infindcommand.Find /I "Name"<"C:\Env\Test\test.xml">"%TEMP%\Test.tmp"?<Org Updated="date" Owner="Test" Version="2/1/3/4"Database="Test" Client="Name">I just want Name in my tmp file and nothing else because i want to store the value (Name) in a variable.Nameor for varying stringSomeNameas a particular value ofClient="SomeName"?