繁体   English   中英

在xml文件中搜索-批处理脚本

[英]search in xml file - batch script

我需要您的批处理脚本(cmd)帮助

我需要编写一个批处理脚本,该脚本将从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>

我的问题是:我需要取位于<version>标记之间的值,我将此行以粗体显示(** <version> 6.6.3-21-DEV-SNAPSHOT **)我尝试了很多事情,但我没办法做到这一点,因为xml中有一些<version>标记,我只需要提到的特定内容。 我需要的版本不是放在父标记下的版本,而是在标记“名称”之后显示的版本。 谢谢!

所以我怎么能把这个值放到变量里呢?

非常感谢!!

@echo off
for /f "tokens=2 delims=<>" %%a in ('type file.xml^|findstr /b "<version>"') do set "version=%%a"
echo %version%

注意:仅当文件的格式正确如您的示例时,这才起作用。 批处理不擅长处理XML。

编辑以反映评论中的最新信息(第二次出现):

@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"

再次:批处理不是XML的好解决方案...

处理XML需要XML感知工具。 您可以暂时摆脱黑客攻击,但是在某些时候这些黑客攻击会失败,所以为什么不从一开始就正确地进行黑客攻击。

选项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>

然后像这样在你的批处理中运行它

msxsl pom.xml get_project_version.xsl

它将立即输出6.6.3-21-DEV-SNAPSHOT

优点:将与您当前的cmd.exe / batch方法一起使用。

缺点:XSLT和XPath具有学习曲线。


选项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"

优势:现代外壳,无外部依赖。

缺点:Powershell和XPath具有学习曲线。

您可以尝试使用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

通过将xml文件解析为xml,您可以避免一些潜在的问题,例如缺少新行等。

这是JavaScript中的Windows脚本宿主文件,它带有2个参数(文件名,XPath),并输出与所提供的XPath匹配的所有节点的所有元素。

取得文件,将其命名为xmlparse.wsf并使用cscript.exe运行它,如下所示。

cscript /nologo xmlparse t.xml "/xml/version" 

您可以选择为那些遭受名称空间过大破坏的用户提供名称空间前缀和名称空间URI。

cscript /nologo xmlparse t.xml "/nso:xml/nso:version" "nso" "http://namespacesRoverkill.com"

确保将默认脚本引擎设置为控制台(而非窗口)输出,如下所示

cscript /H:CScript

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>

如您所指示的,此批处理文件获得出现在标签“名称”之后的版本

@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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM