Разбор XML из партии
Мне нужно проанализировать этот XML-файл и использовать входные данные из полей через пакет Windows. Мне нужно поместить все значения в переменные, я бьюсь головой так много часов, но не могу придумать ничего полезного. Может кто-нибудь, пожалуйста, помогите? Достаточно простого полезного совета.
Мне нужен ответ, который следует нормальному формату программирования, так как сначала мне нужно увидеть тег, а затем, а затем, если есть несколько, я должен проанализировать их в цикле.
<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>
2 ответа
@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
Ну, вероятно, в этом есть некоторые дыры, так что "для экспериментальных целей"
Запустите его, как это имя пакета
Если есть дополнительные теги, добавьте / выберите дополнительные теги
Чтобы установить последовательность полей вывода, добавьте / seq tagsrequiredtobeoutput - по умолчанию используйте обязательные теги + дополнительные теги
Чтобы активировать вывод только между starttag и / starttag, добавьте / block tag
Обработка достаточно проста. Имена тегов встроены в envvars, начиная $
- $tag, $seq и т. д. Строки предполагаются либо <tag>
, </endtag>
или же <tag>data</endtag>
,
Помимо этого, процесс контролируется $mode
(когда установлено: выход), который переключается обработкой block
тег. Данные накапливаются в envvars $$tagname
и будет выводиться только если $mode
swich установлен и есть полный набор 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
Предположим, у вас есть 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
Теперь вы можете сделать это таким образом.