1

If I have xml file with following format, how do I parse it in batch(.bat) script? or is there a way I can only get certain value without parsing it?

For example, I need to get the value of 'date' from this xml file.

<?xml version="1.0" encoding="UTF-8"?>
<note>
<slideshow 
    title="Sample Slide Show"
    date="2016/05/03"
    author="Yours Truly"  >

</slideshow>
</note>
Taewan
  • 947
  • 4
  • 14
  • 24
  • Pure batch scripting is not capable of parsing XML files; I recommend to use a language that supports XML natively (PowerShell, VBScript, JavaScript, etc.?); if you do want a batch file for this, you could even embed another language; if you do not want this either, you need to read the XML file as normal text... – aschipfl May 04 '16 at 09:09

2 Answers2

2

Here's a script that accepts a single argument - the xml file and gets slideshow's node date attribute value. You can alter the xpath query to fits your needs if the file has different structure:

@if (@X)==(@Y) @end /* JScript comment
    @echo off

    rem :: the first argument is the script name as it will be used for proper help message
    cscript //E:JScript //nologo "%~f0" %*

    exit /b %errorlevel%

@if (@X)==(@Y) @end JScript comment */

var objDoc = WScript.CreateObject("MSXML.DOMDocument");
objDoc.load(WScript.Arguments.Item(0));

var objNode = objDoc.selectSingleNode("//slideshow");
WScript.Echo(objNode.getAttribute("date"));

EDIT here's a xpath.bat now - a script for common usage that can parse a xml file.

npocmaka
  • 51,748
  • 17
  • 123
  • 166
  • Thanks for the answer. It works well. I am curious whether i can use the value of 'date' as parameter run another bat script? – Taewan May 04 '16 at 14:59
  • 1
    yes you can - [just call the batch file with for command](http://stackoverflow.com/questions/16203629/batch-assign-command-output-to-variable) – npocmaka May 04 '16 at 15:46
1

Here is a pure solution. The following script expects three command line arguments: the (path to the) XML file, the node (slideshow in your example) and the attribute name (date), in the given order. The return data is output to the console window and can be redirected into a file (>).

This is a sample command line to run the script (supposing the XML file is called presentation.xml, the script is named extract-xml-attrib.bat and the resulting data are to be written to attr.txt):

"extract-xml-attrib.bat" "presentation.xml" "slideshow" "date" > "attr.txt"

This is the code of the script extract-xml-attrib.bat:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "XML=%~1"
set "TAG=%~2"
set "PAR=%~3"

rem // Define defaults here:
if not defined XML set "XML=presentation.xml"
if not defined TAG set "TAG=slideshow"
if not defined PAR set "PAR=date"

set "FLAG="
for /F usebackq^ delims^=^ eol^= %%L in ("%XML%") do (
    set "LINE=%%L"
    setlocal EnableDelayedExpansion
    set "REST=!LINE:*<%TAG%=!"
    if not defined REST (
        set "FLAG=#"
    ) else (
        set "REST=!LINE:*<%TAG% =!"
        if not "!REST!"=="!LINE!" (
            set "FLAG=#"
        ) else (
            set "REST=!LINE:*<%TAG% =!"
            if not "!REST!"=="!LINE!" (
                set "FLAG=#"
            )
        )
    )
    for /F "tokens=1,2 delims=>" %%E in ("!REST!/") do (
        if defined FLAG (
            endlocal
            set "FLAG=#"
        ) else (
            endlocal
        )
        set "REST=%%E"
        if defined FLAG (
            call :GET_ATTR "REST:~,-1" "%PAR%"
        )
        if not "%%F"=="" (
            set "FLAG="
        )
        setlocal EnableDelayedExpansion
    )
    endlocal
)

endlocal
exit /B


:GET_ATTR var_string param_name
setlocal DisableDelayedExpansion
set "PAR=%~2"
setlocal EnableDelayedExpansion
set "STR=!%~1!"
set "NEXT="
for %%S in (!STR!) do (
    if defined NEXT (
        endlocal
        echo(%%~S
        set "NEXT="
        setlocal EnableDelayedExpansion
    )
    set "STR=!STR:*%%S=!"
    if "%%S"=="%PAR%" (
        if defined STR (
            if "!STR:~,1!"=="=" (
                if "!STR:~1,1!"==" " (
                    echo(
                ) else if "!STR:~1,1!"=="   " (
                    echo(
                ) else (
                    set "NEXT=#"
                )
            )
        )
    )
)
if defined NEXT echo(
endlocal
endlocal
exit /B
aschipfl
  • 28,946
  • 10
  • 45
  • 77