[英]BATCH Script - Read XML and return multiple values for the same tag/element and pass it as variable
这是代码,它仅读取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标记并输出以将其作为变量数组传递给批处理脚本的功能-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>
我建议将您的XML解析为XML,而不是将其标记和刮擦为文本。 如果将其解析为XML,那么脚本的成功与否取决于XML是否被美化,丑化,缩小等。 由于批处理语言没有简单的方法来解释XML DOM,因此可以使用批处理+ JScript混合脚本从Windows脚本宿主借用。 使用.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!
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.