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

时间:2015-10-12 15:42:18

标签: xml groovy soapui

我编写了以下代码来验证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) )

请帮助

1 个答案:

答案 0 :(得分:0)

您可以做的是分解每个部分的路径(例如 d mv )然后调用{ {1}}遍历层次结构。这是一个例子。

实施例

Node.getAt(String)

输出为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) } } } Collection。如果您只想要这些值,可以执行此操作:Node返回:example.execute('d.mv.value').collect { it.value().head() }