如何在groovy中将XML节点路径作为参数传递给方法?

如何在groovy中将XML节点路径作为参数传递给方法?,xml,groovy,soapui,Xml,Groovy,Soapui,我编写了以下代码来验证XML节点值。 当我们必须遍历单个节点并打印值时,下面的代码工作正常。 但是,当我尝试遍历到任何子节点并返回节点值时,我无法检索正确的值 //Sample XML (sample_2015-10-12.xml) <a> <b> <c1 Action="C"> <Id>12345</Id> <DisplayName>User1</DisplayN

我编写了以下代码来验证XML节点值。 当我们必须遍历单个节点并打印值时,下面的代码工作正常。 但是,当我尝试遍历到任何子节点并返回节点值时,我无法检索正确的值

//Sample XML (sample_2015-10-12.xml)
<a>
   <b>
      <c1 Action="C">
         <Id>12345</Id>
         <DisplayName>User1</DisplayName>
         <Price>68.0000</Price>
         <d>
            <mv>
               <value>29</value>
            </mv>
         </d>
      </c1>
      <c2 Action="C">
         <Id>12378</Id>
         <DisplayName>User2</DisplayName>
         <Price>70.0000</Price>
         <d>
            <mv>
               <value>30</value>
            </mv>
         </d>
      </c2>   
   </b>
</a>


//Call class example and pass the node path as a parameter
library = testRunner.testCase.testSuite.project.testSuites["XMLValidate"]
module = library.testCases["XMLValidate"].testSteps["validateXML"]
module.run(testRunner, context)
def example = context.example
log.info "example.execute() = " + example.execute("d.mv.value");    


//Traverse the XML node and print the node value
class Example
{
   def log
   def context
   def testRunner
   def xPath

   // Class constructor with same case as Class name
   def Example(logIn,contextIn,testRunnerIn)
   {
      this.log = logIn
      this.context = contextIn
      this.testRunner = testRunnerIn
      this.xPath = xPath
   }
    def execute(xPath)
   {
        log.info xPath
        def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context);
        def XMLPath = context.expand("F:\\Sample_2015-10-12.xml");
        def samplexml = new File(XMLPath).text;
        def root = new XmlParser().parseText( samplexml )
        def strPath = XMLPath.split(Pattern.quote('\\'))
        def strFileName = strPath[strPath.size()-1].split('_');


    int cnt = 0
    switch( strFileName[0] ){
        case "Sample":
            def Var = root.b.c
            log.info Var
            Var.any{
                String intNum = it.Id.collect {it.text()}
                log.info it.Id.collect {it.text()}
                if (intNum.replace('[','').replace(']','') == "12378"){
                    log.info cnt
                    true
                }
                else{
                    cnt = cnt + 1
                    return
                }           
            }

            def Var2 = root.b.c[cnt]."${xPath}"
            log.info Var2.collect {it.text()}
    }


  }
}
context.setProperty( "example", new Example( log, context, testRunner) )
//示例XML(Sample_2015-10-12.XML)
12345
用户1
68
29
12378
用户2
70
30
//调用类示例并将节点路径作为参数传递
library=testRunner.testCase.testSuite.project.testSuite[“XMLValidate”]
module=library.testCases[“XMLValidate”].testSteps[“validateXML”]
module.run(testRunner,context)
def example=context.example
log.info“example.execute()=”+example.execute(“d.mv.value”);
//遍历XML节点并打印节点值
课例
{
def日志
定义上下文
def测试运行程序
defxpath
//与类名大小写相同的类构造函数
def示例(登录、contextIn、testRunnerIn)
{
this.log=登录
this.context=contextIn
this.testRunner=testRunnerIn
this.xPath=xPath
}
def执行(xPath)
{
log.info xPath
def groovyUtils=new com.eviware.soapui.support.groovyUtils(上下文);
def XMLPath=context.expand(“F:\\Sample_2015-10-12.xml”);
def samplexml=新文件(XMLPath).text;
def root=new XmlParser().parseText(samplexml)
def strPath=XMLPath.split(Pattern.quote('\\'))
def strFileName=strPath[strPath.size()-1]。拆分(“”);
int cnt=0
开关(strFileName[0]){
案例“样本”:
def Var=root.b.c
log.info变量
任何变量{
字符串intNum=it.Id.collect{it.text()}
log.info it.Id.collect{it.text()}
if(intNum.replace('[','').replace(']','')=“12378”){
log.info cnt
符合事实的
}
否则{
cnt=cnt+1
回来
}           
}
def Var2=root.b.c[cnt]。“${xPath}”
log.info Var2.collect{it.text()}
}
}
}
setProperty(“示例”,新示例(日志、上下文、testRunner))

请帮助

您可以将路径分解为每个部分(例如d、mv和value),然后调用
Node.getAt(String)
遍历层次结构。这里有一个例子

实例
import groovy.util.XmlParser
导入groovy.util.Node
def数据=“”
12345
用户1
68
29
12378
用户2
70
30
'''
def xml=new XmlParser().parseText(数据)
def example=新示例(xml)
execute('d.mv.value')
执行(['d','mv','value']))
@groovy.transform.TupleConstructor
课例{
节点xml
def执行(字符串路径){
执行(path.tokenize('.'))
}
def执行(列表属性){
def base=xml.b.'*'//这意味着基本路径是a.b.[任何节点]
/* 
*在每个节点上调用Node.getAt(字符串)。
*例如:
*xml.b.'*'.getAt('d').getAt('mv').getAt('value'))
*它与:xml.b.'*'.d.mv.value相同
*/
inject(base){node,propertyName->
node.getAt(propertyName)
}        
}
}
输出是
节点的
集合。如果您只需要值,可以这样做:
example.execute('d.mv.value')。collect{it.value().head()}
返回:
[29,30]

import groovy.util.XmlParser
import groovy.util.Node

def data = '''
<a>
   <b>
      <c1 Action="C">
         <Id>12345</Id>
         <DisplayName>User1</DisplayName>
         <Price>68.0000</Price>
         <d>
            <mv>
               <value>29</value>
            </mv>
         </d>
      </c1>
      <c2 Action="C">
         <Id>12378</Id>
         <DisplayName>User2</DisplayName>
         <Price>70.0000</Price>
         <d>
            <mv>
               <value>30</value>
            </mv>
         </d>
      </c2>   
   </b>
</a>
'''

def xml = new XmlParser().parseText(data)
def example = new Example(xml)

example.execute('d.mv.value')
example.execute(['d', 'mv', 'value'])

@groovy.transform.TupleConstructor
class Example {
    Node xml

    def execute(String path) {
        execute(path.tokenize('.'))
    }

    def execute(List<String> properties) {
        def base = xml.b.'*' // This means the base path is a.b.[ANY NODE]

        /* 
         * Calls Node.getAt(String) on each Node.
         * Example:
         * xml.b.'*'.getAt('d').getAt('mv').getAt('value')
         * which is the same as: xml.b.'*'.d.mv.value
         */
        properties.inject(base) {node, propertyName ->
            node.getAt(propertyName)
        }        
    }
}