Разбор 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

Теперь вы можете сделать это таким образом.

Другие вопросы по тегам