1

親ノードとして持つノード リストごとに、最初の 3 つのノード、つまりとListsの変数値を取得/保存したいと考えています。私は vbscript でそれを行う方法を知っていますが、バッチでソリューションを提供する方がはるかに興味深いです。お願いします、できますか?entryoutputtoken

   <list1>
      <entry>myEntry</entry>
      <output>myOut</output>
      <token>4</token>
              <status>1</status>          
              <number>6</number>
      <!-- Comments -->       
       </list1>

     <list2>
      <entry>newEntry</entry>
      <output>thisOutput</output>
      <token>1</token>
              <status>0</status>          
              <number>1</number>
      <!-- Comments -->       
     </list2>

             <list3>
      <!-- repeat nodes as before -->         
     </list3>

どんな助けでも!!! ありがとう

4

2 に答える 2

1
@ECHO OFF
SETLOCAL
CALL :zapvars
FOR /f "tokens=2,3delims=<>" %%i  IN (myxml.xml) DO (
CALL :analyse %%i
IF DEFINED tlist   SET   list=%%i
IF DEFINED tentry  SET  entry=%%j
IF DEFINED ttoken  SET  token=%%j
IF DEFINED toutput SET output=%%j
)

GOTO :eof

:analyse
FOR %%a IN (tlist tentry ttoken toutput) DO (SET %%a=)
ECHO %1|FINDSTR /b "list" >NUL
IF NOT ERRORLEVEL 1 SET tlist=Y&GOTO :EOF 
IF "%1"=="entry" SET tentry=Y&GOTO :EOF 
IF "%1"=="output" SET toutput=Y&GOTO :EOF 
IF "%1"=="token" SET ttoken=Y&GOTO :EOF 
IF NOT "%1"=="/%list%" GOTO :EOF 
:: Found end of list
ECHO list=%list% entry=%entry% output=%output% token=%token%
:zapvars
FOR %%z IN (list entry output token) DO (SET %%z=)
GOTO :eof

本当にそれほど難しいことではありません。質問は、envvars に入ったら何をしたいかです。明らかに、欠落している要素をチェックしたい場合は、結果のみを使用するだけで済みますif defined list if defined entry if defined output if defined token

入力形式が与えられると、各行は と を使用して<トークン化>されます。最初に選択されたトークンは に適用され%%i、2 番目は に適用されます%%j。行の最初のトークンは先頭のスペースです。

したがって、%%i がノード名になります。行ごとに、ノード名がサブルーチン :analyse に渡されて、分析が行われます。

:analyse は最初に各フラグをクリアします tname意味token is aname . First cab off the rank is to see whether the token startslist , so the token isECHO ed intoFINDSTR which looks for a line beginning (/b`) "list". findstring が探しているものを見つけた場合、ERRORLEVEL は 0 に設定され、そうでない場合は 0 以外に設定されます。

errorlevel が設定されていない場合は1 or greater、SOMETHING に設定されている限り、何にでも設定できます。その後、サブルーチンは終了します。TLISTY

トークンの開始ではなかった場合は、ターゲット トークンごとにルーズになりますlist:analyse見つかった場合は、適切なフラグを設定します。

最後に、トークンがそうでない/LISTNAMEBEINGPROCESSED場合、ルーチンは終了します。/list...IS が見つかった場合、値トークンが表示されてからクリアされます。

一方、FORループに戻ると、 への呼び出しに続いて:analyse、ルーチンの決定は、環境内で SET を開始する ( 、 、)tlisttentry最大1 つに含まれます。tname が設定されている場合、対応する値トークンが適切なメタ変数から割り当てられます - - リスト名が設定されている場合、および- その他のデータ項目。関心のないノードについては、フラグは返されないため、ループは単純に次の行に進みます。ttokentoutput%%itlist%%j:analyseFOR

于 2013-03-30T12:45:45.850 に答える
1

以下のバッチ ファイルは、目的のノードの値を取得/保存し、親ノードごとに処理します。この方法は、プログラム内の1行を変更するだけで処理ノードの数と名前を変更でき、外部コマンド(*.exeファイル)やcallコマンドを使用しないため高速です。

@echo off
setlocal EnableDelayedExpansion
rem Define the names of the desired nodes
set nodes=entry output token
rem Process file lines and get first two tokens separated by <> (ie: %%a=entry, %%b=myEntry)
for /F "tokens=2-3 delims=<>" %%a in (theXMLfile.xml) do (
   set "node=%%a"
   rem If this node is not the end of this record...
   if "!node:~0,5!" neq "/list" (
      rem If this node is one of the desired ones...
      if "!nodes:%%a=!" neq "%nodes%" (
         rem Assign this node into a variable of same name (ie: set entry=myEntry)
         set "%%a=%%b"
      )
   ) else (
      rem ListX node complete: process it, for example:
      ECHO call another.bat !entry! !output! !token!
   )
)

ただし、入力ファイルが非常に大きい場合、callレコードでコマンドを実行すると、プログラムの実行時間が長くなりすぎる可能性があります。プログラムをより高速に実行できるようにする変更は、個々の変数ではなく、すべてのノードを配列に格納し、一度だけ呼び出されるサブルーチンに親ノードの数を渡すことです。

@echo off
setlocal EnableDelayedExpansion
rem Define the names of the desired nodes
set nodes=entry output token
rem Define the index of the next array element
set index=1
rem Process file lines and get first two tokens separated by <> (ie: %%a=entry, %%b=myEntry)
for /F "tokens=2-3 delims=<>" %%a in (theXMLfile.xml) do (
   set "node=%%a"
   rem If this node is not the end of this record...
   if "!node:~0,5!" neq "/list" (
      rem If this node is one of the desired ones...
      if "!nodes:%%a=!" neq "%nodes%" (
         rem Assign this node into THE CURRENT ELEMENT OF AN ARRAY variable of same name (ie: set entry[!index!]=myEntry)
         set "%%a[!index!]=%%b"
      )
   ) else (
      rem ListX node complete: pass to next element of arrays
      set /A index+=1
   )
)
rem Call the subroutine and pass as parameter the number of parent listX nodes
set /A number=index-1
call :anotherSub %number%
goto :EOF

:anotherSub numberOfNodes
rem Process all nodes, for example:
for /L %%i in (1,1,%1) do (
   echo !entry[%%i]! !output[%%i]! !token[%%i]!
)
exit /B

アントニオ

于 2013-03-31T03:03:04.813 に答える