如何在groovy中使用xmlstarlet?

时间:2016-09-13 09:16:15

标签: groovy xmlstarlet

我有一个使用xmlstarlet处理某个xml的bash脚本。 我需要将bash脚本移植到Groovy(使用Jenkins管道),我在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());

enter image description here

1 个答案:

答案 0 :(得分:1)

Groovy只是用参数产生新进程 - 并且没有shell。所以没有必要引用params(哪些shell需要单独留下params)。在这种情况下,引用WHERE analysis.debtor.gender=CASE WHEN ?='Men' THEN 'MALE' ELSE 'FEMALE' END OR (? NOT IN ('Men', 'Female')) 的查询会使其思考,只需要一个常量字符串(请参阅问题中的xmlstarlet)。

所以只需使用OUTPUT: count(//Result/Dataset)进行正确的参数分离,不要引用shell,不要使用shell功能(如管道,重定向......):

[].execute()

如果您需要“shellisms”,请使用

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

或者你的shell如何处理这样的“eval me the line”场景。