正在从批处理中解析 xml
parsing xml from batch
我需要解析此 xml 文件并通过 windows 使用来自字段的输入 batch.i 需要将所有值放入变量中,我正在努力这么多小时,但想不出任何有用的东西。有人可以帮忙吗?一个简单有用的提示就足够了。
我需要一个遵循正常编程格式的答案,因为首先我需要查看标签,然后是,如果有多个,我必须循环解析它们。
<USERS>
<USER>
<USERNAME>FT_NRIAPIUSER </USERNAME>
<PASSWROD>XXXXXXXXXXXXX</PASSWROD>
<GROUPNAME>-</GROUPNAME>
<POLICYNAME>-</POLICYNAME>
<REMARKS>-</REMARKS>
</USER>
<USER>
<USERNAME>FT_SelfAdmin01</USERNAME>
<PASSWROD>XXXXXXXXXXXXX</PASSWROD>
<GROUPNAME>FT_SelfAdmins</GROUPNAME>
<POLICYNAME>-</POLICYNAME>
<REMARKS>-</REMARKS>
</USER>
</USERS>
<GROUPS>
<GROUP>
<GROUPNAME>FT_SelfAdmins</GROUPNAME>
<POLICIES>
<POLICY>
<POLICYNAME>-</POLICYNAME>
</POLICY>
</POLICIES>
<REMARKS>-</REMARKS>
</GROUP>
<GROUP>
<GROUPNAME>FT_SelfUsers</GROUPNAME>
<POLICIES>
<POLICY>
<POLICYNAME>-</POLICYNAME>
</POLICY>
</POLICIES>
<REMARKS>-</REMARKS>
</GROUP>
</GROUPS>
假设你有 z1.xml
<?xml version="1.0" encoding="utf-8" ?>
<USER>
<USERNAME>FT_NRIAPIUSER</USERNAME>
<PASSWORD>XXXXXXXXXXXXX</PASSWORD>
</USER>
你有z2.bat
@echo off
for /f "tokens=2 delims=><" %%a in ('type z1.xml ^| find
"<USERNAME>"') do set ip=%%a
echo User Name is %ip%
for /f "tokens=2 delims=><" %%a in ('type z1.xml ^| find
"<PASSWORD>"') do set ip=%%a
echo Password is %ip%
pause
现在你可以这样操作了。
@ECHO Off
SETLOCAL
::
:: remove variables starting $
FOR /F "delims==" %%a In ('set $ 2^>Nul') DO SET "%%a="
:: evaluate command line. Structure is
:: %1 : filename to be analysed
:: %2 : tag to signal "new data item"
:: %..: other REQUIRED tags
:: then repeat
:: /opt optional tags
:: /block start-analysis tag
:: /seq tags in required output-sequence
::
SET "$filename=%~1"
IF NOT EXIST "%$filename%" ECHO "%~1" NOT found&GOTO :EOF
SET "$mode=tag"
:tagloop
SHIFT
SET "$=%~1"
IF NOT DEFINED $ GOTO process
IF %$:~0,1%==/ (SET "$mode=%$:~1%") ELSE (CALL SET "$%$mode%=%%$%$mode%%% %~1")
GOTO tagloop
:process
:: start mode OFF in block mode, on otherwise
:: establish tag1 (which signals start-of-next-data-item)
IF DEFINED block (SET "$mode=") ELSE (SET "$mode=Y")
FOR %%z IN (%$tag%) DO IF NOT DEFINED $tag1 SET "$tag1=%%z"
:: default output sequence is requiredtags optionaltags
IF NOT DEFINED $seq SET "$seq=%$tag% %$opt%"
CALL :zapvars
FOR /f "usebackqtokens=*" %%L IN ("%$filename%") DO (
FOR /f "tokens=1-3delims=<>" %%a IN ("%%L") DO IF "%%c"=="" (CALL :lonely "%%a") ELSE (CALL :triplet "%%a" "%%b" "%%c")
)
)
GOTO :eof
:: One parameter on line - may be start/end of block
:lonely
FOR %%p IN (%$block%) DO IF /i "%%p"=="%~1" (SET "$mode=Y"&CALL :zapvars) ELSE (
IF /i "/%%p"=="%~1" CALL :output&SET "$mode=")
GOTO :eof
:: presume 3 elements - tag data endtag
:triplet
FOR %%p IN (%$tag1%) DO IF /i "%~1"=="%%p" CALL :output
FOR %%p IN (%$tag% %$opt%) DO IF /i "%~1"=="%%p" SET "$$%%p=%~2"
GOTO :eof
:output
IF NOT DEFINED $mode GOTO zapvars
:: build line for outputting - IF all the required elements are present
FOR %%p IN (%$tag%) DO IF NOT DEFINED $$%%p GOTO zapvars
SET "$line="
FOR %%p IN (%$seq%) DO IF DEFINED $$%%p (CALL SET "$line=%%$line%%,%%$$%%p%%") ELSE (CALL SET "$line=%%$line%%,""")
ECHO %$line:~1%
GOTO zapvars
:zapvars
FOR %%z IN (%$tag% %$opt%) DO SET "$$%%z="
GOTO :eof
好吧 - 可能这里有一些漏洞 - 所以 "for experimental purposes"
运行 它作为 thisbatch filename requiredtags
如果有可选标签,则添加/opt optionaltags
要设置输出字段顺序,添加/seq tagsrequiredtobeoutput - 默认使用requiredtags+optionaltags
要仅在 starttag 和 /starttag 之间激活输出,然后添加 /block 标签
处理相当简单。标签名称内置到 envvars 中,从 $
- $tag、$seq 等开始。假设这些行是 <tag>
、</endtag>
或 <tag>data</endtag>
.
除此之外,该过程由 $mode
控制(设置时:输出),它由 block
标记的处理切换。数据累积到 envvars $$tagname
中,只有在设置了 $mode
开关并且有完整的 required
标签集时才会输出。第一个 required
标签比较特殊,它控制何时开始一个新的数据项(开始一个新的数据项意味着前一个被累加的数据项得到输出)
因此,命令
thisbatch q28540123.txt username passwrod /opt policyname groupname /seq policyname groupname username passwrod /block users
将提取数据 <users>..</users>
,需要 username passwrod
和可选的 policyname groupname
并且在 username
上的每个数据中断(第一个提到的必需元素)将在序列 policyname groupname username passwrod
我需要解析此 xml 文件并通过 windows 使用来自字段的输入 batch.i 需要将所有值放入变量中,我正在努力这么多小时,但想不出任何有用的东西。有人可以帮忙吗?一个简单有用的提示就足够了。
我需要一个遵循正常编程格式的答案,因为首先我需要查看标签,然后是,如果有多个,我必须循环解析它们。
<USERS>
<USER>
<USERNAME>FT_NRIAPIUSER </USERNAME>
<PASSWROD>XXXXXXXXXXXXX</PASSWROD>
<GROUPNAME>-</GROUPNAME>
<POLICYNAME>-</POLICYNAME>
<REMARKS>-</REMARKS>
</USER>
<USER>
<USERNAME>FT_SelfAdmin01</USERNAME>
<PASSWROD>XXXXXXXXXXXXX</PASSWROD>
<GROUPNAME>FT_SelfAdmins</GROUPNAME>
<POLICYNAME>-</POLICYNAME>
<REMARKS>-</REMARKS>
</USER>
</USERS>
<GROUPS>
<GROUP>
<GROUPNAME>FT_SelfAdmins</GROUPNAME>
<POLICIES>
<POLICY>
<POLICYNAME>-</POLICYNAME>
</POLICY>
</POLICIES>
<REMARKS>-</REMARKS>
</GROUP>
<GROUP>
<GROUPNAME>FT_SelfUsers</GROUPNAME>
<POLICIES>
<POLICY>
<POLICYNAME>-</POLICYNAME>
</POLICY>
</POLICIES>
<REMARKS>-</REMARKS>
</GROUP>
</GROUPS>
假设你有 z1.xml
<?xml version="1.0" encoding="utf-8" ?>
<USER>
<USERNAME>FT_NRIAPIUSER</USERNAME>
<PASSWORD>XXXXXXXXXXXXX</PASSWORD>
</USER>
你有z2.bat
@echo off
for /f "tokens=2 delims=><" %%a in ('type z1.xml ^| find
"<USERNAME>"') do set ip=%%a
echo User Name is %ip%
for /f "tokens=2 delims=><" %%a in ('type z1.xml ^| find
"<PASSWORD>"') do set ip=%%a
echo Password is %ip%
pause
现在你可以这样操作了。
@ECHO Off
SETLOCAL
::
:: remove variables starting $
FOR /F "delims==" %%a In ('set $ 2^>Nul') DO SET "%%a="
:: evaluate command line. Structure is
:: %1 : filename to be analysed
:: %2 : tag to signal "new data item"
:: %..: other REQUIRED tags
:: then repeat
:: /opt optional tags
:: /block start-analysis tag
:: /seq tags in required output-sequence
::
SET "$filename=%~1"
IF NOT EXIST "%$filename%" ECHO "%~1" NOT found&GOTO :EOF
SET "$mode=tag"
:tagloop
SHIFT
SET "$=%~1"
IF NOT DEFINED $ GOTO process
IF %$:~0,1%==/ (SET "$mode=%$:~1%") ELSE (CALL SET "$%$mode%=%%$%$mode%%% %~1")
GOTO tagloop
:process
:: start mode OFF in block mode, on otherwise
:: establish tag1 (which signals start-of-next-data-item)
IF DEFINED block (SET "$mode=") ELSE (SET "$mode=Y")
FOR %%z IN (%$tag%) DO IF NOT DEFINED $tag1 SET "$tag1=%%z"
:: default output sequence is requiredtags optionaltags
IF NOT DEFINED $seq SET "$seq=%$tag% %$opt%"
CALL :zapvars
FOR /f "usebackqtokens=*" %%L IN ("%$filename%") DO (
FOR /f "tokens=1-3delims=<>" %%a IN ("%%L") DO IF "%%c"=="" (CALL :lonely "%%a") ELSE (CALL :triplet "%%a" "%%b" "%%c")
)
)
GOTO :eof
:: One parameter on line - may be start/end of block
:lonely
FOR %%p IN (%$block%) DO IF /i "%%p"=="%~1" (SET "$mode=Y"&CALL :zapvars) ELSE (
IF /i "/%%p"=="%~1" CALL :output&SET "$mode=")
GOTO :eof
:: presume 3 elements - tag data endtag
:triplet
FOR %%p IN (%$tag1%) DO IF /i "%~1"=="%%p" CALL :output
FOR %%p IN (%$tag% %$opt%) DO IF /i "%~1"=="%%p" SET "$$%%p=%~2"
GOTO :eof
:output
IF NOT DEFINED $mode GOTO zapvars
:: build line for outputting - IF all the required elements are present
FOR %%p IN (%$tag%) DO IF NOT DEFINED $$%%p GOTO zapvars
SET "$line="
FOR %%p IN (%$seq%) DO IF DEFINED $$%%p (CALL SET "$line=%%$line%%,%%$$%%p%%") ELSE (CALL SET "$line=%%$line%%,""")
ECHO %$line:~1%
GOTO zapvars
:zapvars
FOR %%z IN (%$tag% %$opt%) DO SET "$$%%z="
GOTO :eof
好吧 - 可能这里有一些漏洞 - 所以 "for experimental purposes"
运行 它作为 thisbatch filename requiredtags
如果有可选标签,则添加/opt optionaltags
要设置输出字段顺序,添加/seq tagsrequiredtobeoutput - 默认使用requiredtags+optionaltags
要仅在 starttag 和 /starttag 之间激活输出,然后添加 /block 标签
处理相当简单。标签名称内置到 envvars 中,从 $
- $tag、$seq 等开始。假设这些行是 <tag>
、</endtag>
或 <tag>data</endtag>
.
除此之外,该过程由 $mode
控制(设置时:输出),它由 block
标记的处理切换。数据累积到 envvars $$tagname
中,只有在设置了 $mode
开关并且有完整的 required
标签集时才会输出。第一个 required
标签比较特殊,它控制何时开始一个新的数据项(开始一个新的数据项意味着前一个被累加的数据项得到输出)
因此,命令
thisbatch q28540123.txt username passwrod /opt policyname groupname /seq policyname groupname username passwrod /block users
将提取数据 <users>..</users>
,需要 username passwrod
和可选的 policyname groupname
并且在 username
上的每个数据中断(第一个提到的必需元素)将在序列 policyname groupname username passwrod