繁体   English   中英

如何在Groovy中使用xmlstarlet?

[英]How can I use xmlstarlet in groovy?

我有一个使用xmlstarlet处理一些xml的bash脚本。 我需要将bash脚本移植到Groovy(以使用Jenkins Pipeline),并且在xml处理部分遇到问题 我知道可以使用GPath,但如果可能的话,我对使用xmlstarlet感兴趣。 这是我的bash脚本的简化:

count=$(xmlstarlet sel -t -v "count(//Result/Dataset[@name='PackageMap_Dataset']/Row)" /tmp/DataPipeLineScript-output-step4.xml)
echo count

为了实现它,我尝试了这个Groovy,但是脚本得到了错误的输出:

def count="xmlstarlet sel -t -v \"count(//Result/Dataset[@name='PackageMap_Dataset']\" DataPipeLineScript-output-step4.xml".execute().text
println "Number of detected DataSets: " + count

没有@name的简化版本具有相同的问题:

def count="xmlstarlet sel -t -v 'count(//Result/Dataset' DataPipeLineScript-output-step4.xml".execute().text
println "Number of detected DataSets: " + count

即使这个简单的执行也失败了,没有输出:

println "xmlstarlet".execute().text
def count= "xmlstarlet".execute().text
println "Number of detected DataSets: " + count

我该如何进行这项工作?

供参考的是xml

<Result>
<Dataset name='PackageMap_Dataset'>
  <queryname>getcoordmissinglocations</queryname>
 <Row>
  <superfilename>~foo::indexes::develop::LocationsToEnrich::Super</superfilename>
  <indexfilename>~foo::indexes::develop::LocationsToEnrich_20160912_143427</indexfilename>
 </Row>
 <Row>
    <queryname>getcoordmissingsoiltype</queryname>
    <superfilename>~foo::indexes::develop::SoilTypesToEnrich::Super</superfilename>
    <indexfilename>~foo::indexes::develop::SoilTypesToEnrich_20160912_143427</indexfilename>
</Row>
 <Row>
    <queryname>getngrmissinglatlong</queryname>
    <superfilename>~foo::indexes::develop::LatLongsToEnrich::Super</superfilename>
    <indexfilename>~foo::indexes::develop::LatLongsToEnrich_20160912_143427</indexfilename>
</Row>
</Dataset>
<Dataset name='Result 2'>
</Dataset>
<Dataset name='Result 3'>
</Dataset>
<Dataset name='Result 4'>
</Dataset>
</Result>

更新我已更新代码以显示@cfrick建议的错误

        //def proc = "xmlstarlet sel -t -v 'count(//Result/Dataset)' DataPipeLineScript-output-step4.xml".execute();
        def proc = ["xmlstarlet", "sel", "-t", "-v", "\"count(//Result/Dataset)\"","DataPipeLineScript-output-step4.xml"].execute()
        def outputStream = new StringBuffer();
        def errorStream = new StringBuffer();
        proc.waitForProcessOutput(outputStream, errorStream);
        println("OUTPUT: " + outputStream.toString());
        println("ERROR: " + errorStream.toString());

在此处输入图片说明

Groovy只是生成带有参数的新进程-而且不是shell。 因此,无需引用参数(这些壳需要保留参数)。 在这种情况下,对xmlstarlet查询的引用会使人想,只是想返回一个常量字符串(请参阅问题中的OUTPUT: count(//Result/Dataset) )。

因此,只需使用[].execute()进行适当的参数分隔,不要引用shell,不要使用shell功能(例如管道,重定向等):

["xmlstarlet", "sel", "-t", "-v", "count(//Result/Dataset)", "DataPipeLineScript-output-step4.xml"].execute()

如果您需要“空壳主义”,请使用

["sh", "-c", "... | ... > 'quote weird files.txt' ..."].execute()

或您的外壳如何处理这种“评估该行”情况。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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