1

对于Lists作为其父节点的每个节点列表,我想获取/保存到前三个节点的变量值中,entryoutputtoken。我知道如何使用 vbscript 来做到这一点,但对我来说批量解决方案更有趣。请问,可以吗?

   <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

真的没那么难。问题是一旦它在环境变量中你想用它做什么。显然,如果你想检查缺失的元素,你需要做的就是只使用结果if defined list if defined entry if defined output if defined token

给定输入格式,每行都使用<和标记化>。第一个选定的标记应用于 ,%%i第二个应用于%%j。行中的第一个标记是前导空格。

因此 %%i 将是节点名称。对于每一行,节点名称被传递给子例程 :analysis for er, analysis。

:analysis 首先清除每个标志 tname表示token is a名称. First cab off the rank is to see whether the token starts列表, so the token isECHO ed intoFINDSTR which looks for a line beginning (/b`) "list"。如果 findstring 找到它要查找的内容,则 ERRORLEVEL 设置为 0,否则设置为非零。

如果 errorlevel 不是1 or greater,则TLIST设置为Y它可以设置为任何值 - 只要它设置为 SOMETHING。然后子程序退出。

如果它不是一个令牌开始,list那么:analyse每个目标令牌都会丢失。如果它找到一个,它会设置适当的标志。

最后,如果令牌不是,/LISTNAMEBEINGPROCESSED则例程退出。如果/list...找到 IS,则显示值标记然后清除。

同时,回到FOR循环中,在调用:analyse之后,例程的决定最多包含在环境中的 ( tlist, tentry, ttoken, toutput) 中的一个中 ( , , , )。如果设置了 tname,则从适当的元变量中分配相应的值标记%%i- 如果tlist设置了列表名称,并且%%j- 其他的数据项。对于不感兴趣的节点,不返回任何标志,:analyse因此FOR循环简单地进行到下一行。

于 2013-03-30T12:45:45.850 回答
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 回答