使用批处理文件在 xml 的特定标签之间打印字符串
Print string between specific Tag from xml using batch file
我的 xml 格式如下:
<?xml version="1.0" encoding="UTF-8"?>
<data>
<wsp1>
<name>
wsp1
</name>
</wsp1>
<feature1>
<name>
feature1
</name>
</feature1>
</data>
我想打印标签 <name></name>
.
之间的所有字符串
我正在使用批处理文件使用以下命令:
@echo off
setlocal enableextensions enabledelayedexpansion
set "xmlFile=testing.xml"
for /f "tokens=1,2 delims=:" %%n in ('findstr /n /i /c:"<name>" "%xmlFile%"') do (
for /f "tokens=*" %%l in ('type "%xmlFile%" ^| more +%%n') do set "location=%%l" & goto endLoop
)
:endLoop
echo %location%
但这只给了我第一个wsp1
。
我只想要所有 <name>
标签之间的所有字符串。
for /f "skip=2tokens=*" %a in ('find /v "<" q34149585.txt') do @echo %a
根据提示应该按照您的要求去做。
"find" 找到包含 <
的所有行 not 但在输出之前有 2 行 - 一行空白,一行带有文件名,所以 skip=2
删除那些行。
您需要更改文件名以适合您的情况。
(for /f "skip=2tokens=*" %a in ('find /v "<" q34149585.txt') do @echo %a)>outfilename.txt
会将结果放入新文件中。
响应后:要求生成 "name" 标签下所有条目的列表,而不是 "all string between tag"
如果您要在其他标签之间添加数据并显示所需的输出,将会有所帮助。
@ECHO Off
SETLOCAL
SET "printme="
SET "tagrequired=name"
FOR /f "tokens=*" %%a IN (q34149585.txt) DO (
IF /i "%%a"=="</%tagrequired%>" SET "printme="
IF DEFINED printme ECHO %%a
IF /i "%%a"=="<%tagrequired%>" SET "printme=Y"
)
GOTO :EOF
我使用了一个名为 q34149585.txt
的文件,其中包含您的数据用于我的测试。
printme
在开始和遇到 </name>
时设置为 nothing,在遇到 <name>
[ 时设置为 Y
=25=]
所以 - 序列
<name>
wsp1
</name>
会将 printme
设置为 Y,然后显示数据值,然后将 printme
设置为 nothing。 if defined
适用于当前(运行 时间)值。
tag1 或 tag2 的调整
@ECHO Off
SETLOCAL
SET "printme="
SET "tagrequired=name"
SET "tag2=whatever"
FOR /f "tokens=*" %%a IN (q34149585.txt) DO (
IF /i "%%a"=="</%tagrequired%>" SET "printme="
IF /i "%%a"=="</%tag2%>" SET "printme="
IF DEFINED printme ECHO %%a
IF /i "%%a"=="<%tagrequired%>" SET "printme=Y"
IF /i "%%a"=="<%tag2%>" SET "printme=Y"
)
GOTO :EOF
将 XML 解析和操作为 XML 通常更优雅,而不是作为文本来抓取和破解。这样您就不会那么依赖于预期您正在操作的文件的格式——例如,标记中间的换行符。为此,我建议您使用 Windows 脚本宿主并使用 Microsoft.XMLDOM
COM 对象来操作 XML DOM.
以下批处理 + JScript 混合示例应使用 .bat 扩展名保存。
@if (@CodeSection == @Batch) @then
@echo off
setlocal
cscript /nologo /e:JScript "%~f0" "test.xml"
goto :EOF
@end // end batch / begin JScript chimera
String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ''); }
var DOM = WSH.CreateObject('Microsoft.XMLDOM'),
xmlfile = WSH.Arguments(0),
XPath = "//name/text()";
DOM.load(xmlfile);
DOM.async = false;
DOM.setProperty('SelectionLanguage', 'XPath');
for (var d = DOM.selectNodes(XPath), i = 0; i < d.length; i++)
WSH.Echo(d[i].data.trim());
如果您愿意,可以添加 XML 文件的验证,以便更好地处理错误,方法是将其插入 DOM.setProperty
行下方:
if (DOM.parseError.errorCode) {
var e = DOM.parseError;
WSH.StdErr.WriteLine('Error in ' + xmlfile + ' line ' + e.line + ' char '
+ e.linepos + ':\n' + e.reason + '\n' + e.srcText);
WSH.Quit(1);
}
如果您想要两个不同标签之间的文本,只需更改 XPath 选择器即可。要在名为 tag1
和 tag2
的标签中搜索,它将如下所示:
XPath = "//*[self::tag1 or self::tag2]/text()";
下载xidel,可以做xpath:
xidel file.xml -e "//name"
我的 xml 格式如下:
<?xml version="1.0" encoding="UTF-8"?>
<data>
<wsp1>
<name>
wsp1
</name>
</wsp1>
<feature1>
<name>
feature1
</name>
</feature1>
</data>
我想打印标签 <name></name>
.
之间的所有字符串
我正在使用批处理文件使用以下命令:
@echo off
setlocal enableextensions enabledelayedexpansion
set "xmlFile=testing.xml"
for /f "tokens=1,2 delims=:" %%n in ('findstr /n /i /c:"<name>" "%xmlFile%"') do (
for /f "tokens=*" %%l in ('type "%xmlFile%" ^| more +%%n') do set "location=%%l" & goto endLoop
)
:endLoop
echo %location%
但这只给了我第一个wsp1
。
我只想要所有 <name>
标签之间的所有字符串。
for /f "skip=2tokens=*" %a in ('find /v "<" q34149585.txt') do @echo %a
根据提示应该按照您的要求去做。
"find" 找到包含 <
的所有行 not 但在输出之前有 2 行 - 一行空白,一行带有文件名,所以 skip=2
删除那些行。
您需要更改文件名以适合您的情况。
(for /f "skip=2tokens=*" %a in ('find /v "<" q34149585.txt') do @echo %a)>outfilename.txt
会将结果放入新文件中。
响应后:要求生成 "name" 标签下所有条目的列表,而不是 "all string between tag"
如果您要在其他标签之间添加数据并显示所需的输出,将会有所帮助。
@ECHO Off
SETLOCAL
SET "printme="
SET "tagrequired=name"
FOR /f "tokens=*" %%a IN (q34149585.txt) DO (
IF /i "%%a"=="</%tagrequired%>" SET "printme="
IF DEFINED printme ECHO %%a
IF /i "%%a"=="<%tagrequired%>" SET "printme=Y"
)
GOTO :EOF
我使用了一个名为 q34149585.txt
的文件,其中包含您的数据用于我的测试。
printme
在开始和遇到 </name>
时设置为 nothing,在遇到 <name>
[ 时设置为 Y
=25=]
所以 - 序列
<name>
wsp1
</name>
会将 printme
设置为 Y,然后显示数据值,然后将 printme
设置为 nothing。 if defined
适用于当前(运行 时间)值。
tag1 或 tag2 的调整
@ECHO Off
SETLOCAL
SET "printme="
SET "tagrequired=name"
SET "tag2=whatever"
FOR /f "tokens=*" %%a IN (q34149585.txt) DO (
IF /i "%%a"=="</%tagrequired%>" SET "printme="
IF /i "%%a"=="</%tag2%>" SET "printme="
IF DEFINED printme ECHO %%a
IF /i "%%a"=="<%tagrequired%>" SET "printme=Y"
IF /i "%%a"=="<%tag2%>" SET "printme=Y"
)
GOTO :EOF
将 XML 解析和操作为 XML 通常更优雅,而不是作为文本来抓取和破解。这样您就不会那么依赖于预期您正在操作的文件的格式——例如,标记中间的换行符。为此,我建议您使用 Windows 脚本宿主并使用 Microsoft.XMLDOM
COM 对象来操作 XML DOM.
以下批处理 + JScript 混合示例应使用 .bat 扩展名保存。
@if (@CodeSection == @Batch) @then
@echo off
setlocal
cscript /nologo /e:JScript "%~f0" "test.xml"
goto :EOF
@end // end batch / begin JScript chimera
String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ''); }
var DOM = WSH.CreateObject('Microsoft.XMLDOM'),
xmlfile = WSH.Arguments(0),
XPath = "//name/text()";
DOM.load(xmlfile);
DOM.async = false;
DOM.setProperty('SelectionLanguage', 'XPath');
for (var d = DOM.selectNodes(XPath), i = 0; i < d.length; i++)
WSH.Echo(d[i].data.trim());
如果您愿意,可以添加 XML 文件的验证,以便更好地处理错误,方法是将其插入 DOM.setProperty
行下方:
if (DOM.parseError.errorCode) {
var e = DOM.parseError;
WSH.StdErr.WriteLine('Error in ' + xmlfile + ' line ' + e.line + ' char '
+ e.linepos + ':\n' + e.reason + '\n' + e.srcText);
WSH.Quit(1);
}
如果您想要两个不同标签之间的文本,只需更改 XPath 选择器即可。要在名为 tag1
和 tag2
的标签中搜索,它将如下所示:
XPath = "//*[self::tag1 or self::tag2]/text()";
下载xidel,可以做xpath:
xidel file.xml -e "//name"