[英]search in xml file - batch script
I need your help in batch script (cmd) 我需要您的批处理脚本(cmd)帮助
I need to write a batch script which take a specific value from xml file and put it into a variable. 我需要编写一个批处理脚本,该脚本将从xml文件中获取特定值并将其放入变量中。
So this is the xml: 所以这是xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>parent-k</artifactId>
<groupId>cyt</groupId>
<version>6.6.3.22-1-DEV-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<groupId>ctx.d</groupId>
<artifactId>view-ct</artifactId>
<packaging>war</packaging>
<name>ctrer</name>
<version>6.6.3-21-DEV-SNAPSHOT</version>
<properties>
<view-core.version>6.6.3.22-1-DEV-SNAPSHOT</view-core.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>8.1.5.v20120716</version>
<configuration>
<stopPort>9966</stopPort>
<stopKey>vaadin</stopKey>
<scanTargets>
<scanTarget>src/main/webapp</scanTarget>
</scanTargets>
<!-- Redeploy every x seconds if changes are detected, 0 for no automatic
redeployment -->
<scanIntervalSeconds>1</scanIntervalSeconds>
<webApp>
<contextPath>/</contextPath>
<configurationClasses>
<configurationClass>org.mortbay.jetty.plugin.MavenWebInfConfiguration</configurationClass>
<configurationClass>org.eclipse.jetty.webapp.WebXmlConfiguration</configurationClass>
<!-- <configurationClass>org.eclipse.jetty.webapp.FragmentConfiguration</configurationClass>
<configurationClass>org.eclipse.jetty.plus.webapp.EnvConfiguration</configurationClass>
<configurationClass>org.eclipse.jetty.plus.webapp.PlusConfiguration</configurationClass>
<configurationClass>org.mortbay.jetty.plugin.MavenAnnotationConfiguration</configurationClass>
<configurationClass>org.eclipse.jetty.webapp.JettyWebXmlConfiguration</configurationClass> -->
</configurationClasses>
</webApp>
</configuration>
</plugin>
</plugins>
</build>
My question is: I need to take the value which is located between the < version > tags, I put this line in bold ( ** < version >6.6.3-21-DEV-SNAPSHOT **) I tried many things but I didn't manage to do it because there are some < version > tags in the xml, and I need only the specific that I mentioned. 我的问题是:我需要取位于<version>标记之间的值,我将此行以粗体显示(** <version> 6.6.3-21-DEV-SNAPSHOT **)我尝试了很多事情,但我没办法做到这一点,因为xml中有一些<version>标记,我只需要提到的特定内容。 The version that I need isn't the version which is placed under the parent tag, but this is the version which appears after the tag "name".
我需要的版本不是放在父标记下的版本,而是在标记“名称”之后显示的版本。 thanks!
谢谢!
so how can I take this value and put it into a variable? 所以我怎么能把这个值放到变量里呢?
Thanks a lot!! 非常感谢!!
@echo off
for /f "tokens=2 delims=<>" %%a in ('type file.xml^|findstr /b "<version>"') do set "version=%%a"
echo %version%
Note: this only works, when the file is exactly formatted as your example. 注意:仅当文件的格式正确如您的示例时,这才起作用。 Batch isn't good at processing XML.
批处理不擅长处理XML。
EDIT to reflect newest info from comments (get the second occurence): 编辑以反映评论中的最新信息(第二次出现):
@echo off
setlocal
set count=0
for /f "tokens=3 delims=<>" %%a in ('type file.xml^|find /i "<version>"') do call :getit "%%a"
echo %version%
goto :eof
:getit
echo ---- %1
set /a count+=1
if %count%==2 set "version=%~1"
again: batch is no good solution for XML... 再次:批处理不是XML的好解决方案...
Processing XML requires XML-aware tools. 处理XML需要XML感知工具。 You can get away with hacks for a while, but at some point these hacks are going to fail, so why not do it properly right from the start.
您可以暂时摆脱黑客攻击,但是在某些时候这些黑客攻击会失败,所以为什么不从一开始就正确地进行黑客攻击。
Option 1 : You could download msxsl.exe , and use an XSLT stylesheet that only extracts a single value: 选项1 :您可以下载msxsl.exe ,并使用仅提取单个值的XSLT样式表:
<!-- get_project_version.xsl -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:maven="http://maven.apache.org/POM/4.0.0"
>
<xsl:output method="text" encoding="Windows-1252" />
<xsl:template match="/">
<xsl:value-of select="/maven:project/maven:version" />
</xsl:template>
</xsl:stylesheet>
and run it like so in your batch 然后像这样在你的批处理中运行它
msxsl pom.xml get_project_version.xsl
which will instantly outputs 6.6.3-21-DEV-SNAPSHOT
. 它将立即输出
6.6.3-21-DEV-SNAPSHOT
。
Advantage: Will work with your current cmd.exe/batch approach. 优点:将与您当前的cmd.exe / batch方法一起使用。
Disadvantage: XSLT and XPath have a learning curve. 缺点:XSLT和XPath具有学习曲线。
Option 2 : Use Powershell, it has this capability built-in, with the Select-Xml
cmdlet. 选项2 :使用Powershell,它具有
Select-Xml
cmdlet内置的此功能。
$ns = @{"maven"="http://maven.apache.org/POM/4.0.0"}
$result = Select-Xml pom.xml -XPath "/maven:project/maven:version" -Namespace $ns
$result.Node."#text"
Advantage: Modern shell, no external dependencies. 优势:现代外壳,无外部依赖。
Disadvantage: Powershell and XPath have a learning curve. 缺点:Powershell和XPath具有学习曲线。
You can try with the xpath.bat (without need to download external binaries).As your xml is not valid I've added a root element: 您可以尝试使用xpath.bat (无需下载外部二进制文件)。由于您的xml无效,因此我添加了一个root元素:
@echo off
echo ^<root^> >temp.xml
type version.xml >>temp.xml
echo ^</root^> >>temp.xml
for /f "tokens=* delims=" %%a in ('xpath.bat temp.xml "root/version"') do set "version=%%a"
echo %version%
del /q /f temp.xml
With parsing xml file as xml you'll avoid some potential problems as missing new lines and etc. 通过将xml文件解析为xml,您可以避免一些潜在的问题,例如缺少新行等。
Here's Windows Scripting Host file in JavaScript that takes 2 parameters (filename, XPath), and outputs all elements of all nodes that match the XPath provided. 这是JavaScript中的Windows脚本宿主文件,它带有2个参数(文件名,XPath),并输出与所提供的XPath匹配的所有节点的所有元素。
Take the file, name it xmlparse.wsf and run it with cscript.exe as follows. 取得文件,将其命名为xmlparse.wsf并使用cscript.exe运行它,如下所示。
cscript /nologo xmlparse t.xml "/xml/version"
You can optionally provide a namespace prefix and namespace URI, for those suffering from namespace overkill. 您可以选择为那些遭受名称空间过大破坏的用户提供名称空间前缀和名称空间URI。
cscript /nologo xmlparse t.xml "/nso:xml/nso:version" "nso" "http://namespacesRoverkill.com"
Be sure to set your default script engine to the console (not window) output, as follows 确保将默认脚本引擎设置为控制台(而非窗口)输出,如下所示
cscript /H:CScript
The actual script for xmlparse.wsf xmlparse.wsf的实际脚本
<package>
<job id="t1">
<script language="JScript">
var fso = new ActiveXObject( "Scripting.FileSystemObject" );
var objArgs = WScript.Arguments;
var strDOMObject = "MSXML2.FreeThreadedDOMDocument";
var xml = new ActiveXObject( this.strDOMObject );
if( objArgs.length < 2 ) {
WScript.Echo( "Usage: file.xml xpath [namespace] [namespaceuri]" );
WScript.Echo( "Outputs the value(s) of all matching nodes" );
WScript.Quit( 1 );
}
var strFileName = objArgs(0);
var strXPath = objArgs(1);
var strNamespacePrefix = null;
var strNamespaceURI = null;
if (fso.FileExists(strFileName) == false) {
WScript.Echo( "Cannot locate " + strFileName );
WScript.Quit( 1 );
}
if( objArgs.length == 3 ) {
WScript.Echo( "Please include both a namespace and namespaceuri" );
WScript.Quit( 1 );
}
// namespace prefix and URI provided, load 'em up
if( objArgs.length == 4 ) {
strNamespacePrefix = objArgs(2);
strNamespaceURI = objArgs(3);
}
try {
if( !xml.load( strFileName ) ) {
var strErrMsg = '';
strErrMsg = xml.parseError.reason;
if( xml.parseError.srcText != "" )
strErrMsg += "Source: " + xml.parseError.srcText + "\r\n";
if( xml.parseError.line != 0 )
strErrMsg += "Line: " + xml.parseError.line + "\r\n";
if( xml.parseError.linepos != 0 )
strErrMsg += "Position: " + xml.parseError.linepos + "\r\n";
throw new Error( xml.parseError.errorCode, strErrMsg );
}
if( strNamespacePrefix != null ) {
xml.setProperty( "SelectionNamespaces", "xmlns:" + strNamespacePrefix + "='" + strNamespaceURI + "'");
}
var nodeList = xml.selectNodes( strXPath );
if( nodeList != null ) {
for( var i = 0; i < nodeList.length; i++ ) {
WScript.Echo( nodeList[i].text );
}
} else {
WScript.Echo( "No matching nodes found in " + strFileName + " with XPath \"" + strXPath + "\"" );
WScript.Quit( 1 );
}
WScript.Quit( 0 ); // success
} catch( e) {
WScript.Echo( e.description );
}
</script>
</job>
</package>
This Batch file get the version which appears after the tag "name" , as you indicated. 如您所指示的,此批处理文件获得出现在标签“名称”之后的版本 。
@echo off
setlocal EnableDelayedExpansion
set "tag="
for /F "tokens=2,3 delims=<>" %%a in ('findstr /N "<name> <version>" file.xml') do (
if "!tag!" equ "name" set "version=%%b"
set "tag=%%a"
)
echo Version: %version%
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.