BATCH脚本 – 读取XML并为同一个标记/元素返回多个值,并将其作为variables传递

这是代码,它只读取xml文件中的最后一个TargetEndpoint标记,并将输出作为 – Facebook

@echo off setlocal enableextensions EnableDelayedExpansion set input="TP.xml" for /f "tokens=3 delims=<> " %%i in ('type %input% ^|find "TargetEndpoint"') do set "targetsName=%%i" echo %targetsName%" 

我们希望能够读取所有TargetEndpoint标签并输出,以便将其作为variables数组传递给批处理脚本 – Apple,Google,Microsoft,Adobe,Facebook

XML文件供参考:

  <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Name revision="1" name="myname"> <ConfigurationVersion majorVersion="4" minorVersion="0"/> <Description>myxml</Description> <Policies> <!--test1 --> </Policies> <Resources> <!--test1 --> </Resources> <TargetServers/> <TargetEndpoints> <TargetEndpoint>Apple</TargetEndpoint> <TargetEndpoint>Google</TargetEndpoint> <TargetEndpoint>Microsoft</TargetEndpoint> <TargetEndpoint>Adobe</TargetEndpoint> <TargetEndpoint>Facebook</TargetEndpoint> </TargetEndpoints> <validate>false</validate> </Name> 

Solutions Collecting From Web of "BATCH脚本 – 读取XML并为同一个标记/元素返回多个值,并将其作为variables传递"

我建议将XML解析为XML,而不是将其标记为文本。 如果将它解析为XML,那么脚本的成功将不会取决于XML是否被美化,丑化,缩小等等。 由于批处理语言没有简单的方法来解释XML DOM,因此可以使用批处理+ JScript混合脚本从Windows Script Host借用。 用.bat扩展名保存,然后试一下。

 @if (@CodeSection == @Batch) @then @echo off setlocal set "XMLfile=test.xml" set "nodes=TargetEndpoint" rem // build array of text node values for TargetEndpoint nodes set "Ubound=-1" for /f "delims=" %%I in ( 'cscript /nologo /e:JScript "%~f0" "%XMLfile%" "%nodes%"' ) do ( set "%%I" set /a Ubound += 1 ) rem // display array set %nodes% rem // demonstrate retrieval of a value setlocal enabledelayedexpansion echo Last element: %nodes%[%Ubound%] = !%nodes%[%Ubound%]! endlocal goto :EOF @end // end batch / begin JScript chimera String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ''); } var DOM = WSH.CreateObject('Microsoft.XMLDOM'), args = { file: WSH.Arguments(0), node: WSH.Arguments(1) }, XPath = "//" + args.node + "/text()"; DOM.load(args.file); DOM.async = false; DOM.setProperty('SelectionLanguage', 'XPath'); if (DOM.parseError.errorCode) { var e = DOM.parseError; WSH.StdErr.WriteLine('Error in ' + args.file + ' line ' + e.line + ' char ' + e.linepos + ':\n' + e.reason + '\n' + e.srcText); WSH.Quit(1); } for (var d = DOM.selectNodes(XPath), i = 0; i < d.length; i++) { WSH.Echo(args.node + '[' + i + ']=' + d[i].nodeValue.trim()); } 

实际上,您可以使用PowerShell做一些类似的操作。 如果你的XML的结构是静态的,你不需要通过XPath进行搜索,你可以这样做:

 powershell "[xml]$x = (gc test.xml); $x.Name.TargetEndpoints.TargetEndpoint" 

或者,如果需要XPath来选择TargetEndpoint节点:

 powershell "select-xml '//TargetEndpoint/text()' test.xml | %{ $_.node.data }" 

建议PowerShell的XML解析器比Microsoft.XMLDOM COM对象更严格。 上面的示例XML将与PowerShell XML解析器错误,因为<?xml?>声明前面有空格。 Jscript,另一方面,似乎并不在乎。

你的问题只是一个简单的支架问题。 您需要在循环内对set和echo命令进行分组,这将在循环时打印每个循环。 它目前只打印了facebook,它是在列表中找到的最后一个,一旦循环完成,就存储在变量中。

例如:

  @echo off setlocal enableextensions EnableDelayedExpansion set input="TP.xml" for /F "tokens=3 delims=<>" %%I in ('type %input% ^|find "TargetEndpoint"') do ( set targetendpoint=%%I echo !targetendpoint! )