【问题标题】:Parse XML using Groovy and XmlSlurper and iterate the tags使用 Groovy 和 XmlSlurper 解析 XML 并迭代标签
【发布时间】:2014-02-10 06:43:00
【问题描述】:

我能够使用 Groovy 和 XmlSlurper 通过 HTTP URL 解析 XML 并输出与标签关联的值。下面是生成的示例 XML 页面。

<worklog>
   <worklog_id>10100</worklog_id>
   <issue_key>TST-3</issue_key>
   <hours>2.0</hours>
   <work_date>2014-01-01</work_date>
   <work_date_time>2014-01-01 00:00:00</work_date_time>
   <username>admin</username>
   <reporter>admin</reporter>
</worklog>
<worklog>
   <worklog_id>10200</worklog_id>
   <issue_key>TST-3</issue_key>
   <work_date>2014-01-02</work_date>
   <work_date_time>2014-01-02 00:00:00</work_date_time>
   <username>admin</username>
   <reporter>admin</reporter>
</worklog>
<worklog>
   <worklog_id>10201</worklog_id>
   <issue_key>TST-3</issue_key>
   <hours>0.25</hours>
   <work_date>2014-01-02</work_date>
   <work_date_time>2014-01-02 10:33:00</work_date_time>
    <username>admin</username>
   <reporter>admin</reporter>
 </worklog>
<worklog>
   <worklog_id>10400</worklog_id>
   <issue_key>TST-3</issue_key>
   <hours>2.0</hours>
   <work_date>2014-01-07</work_date>
   <work_date_time>2014-01-07 12:03:00</work_date_time>
    <username>admin</username>
   <reporter>admin</reporter>
 </worklog>
<worklog>
   <worklog_id>10202</worklog_id>
   <issue_key>TST-4</issue_key>
   <hours>1.0</hours>
   <work_date>2014-01-02</work_date>
   <work_date_time>2014-01-02 15:52:00</work_date_time>
   <username>admin</username>
   <reporter>admin</reporter>
 </worklog>

但是,在我的 XML 中,我需要遍历我的 XML 并查找具有相同值的 issue_key 标记。如果有多个 issue_key 标签具有相同的值,如这里的“TST-3”, 然后我想收集和合并与小时 work_date、work_date_time、username、activity_name、work_description、parent_key、reporter 标签相关的值,然后以它与其他标签的生成顺序相同的顺序输出不同的 issue_key 值。

很抱歉成为 Groovy 和 XmlSlurper 的新手。但是任何人都可以让我知道如何去做。另外,下面是我从 XML 中获取属性的 Groovy 代码。

def worklogList = new ArrayList<Worklog>()
    def wklog
    def worklogs = new XmlSlurper().parse(new File("C:\\xml-worklog\\worklog.xml"))
    worklogs.worklog.each {node ->
        wklog = new Worklog();

        wklog.work_date = node.work_date
        wklog.work_date_time = node.work_date_time
        wklog.issue_key = node.issue_key
        wklog.hours = node.hours
        wklog.username = node.username
        wklog.reporter = node.reporter
        worklogList.add(wklog)
    }
    worklogList.each {wklogT -> println(wklogT)}
}

class Worklog
{
String issue_key
String hours
String work_date
String work_date_time
String username
String activity_name
String work_descripton
String reporter

    @Override
    public String toString()
    {
        return "Issue Key: ${issue_key} \t Hours: ${hours} \t Work Date: ${work_date} \t Work Date Time: ${work_date_time} \t Username: ${username} \t Reporter: ${reporter} \t Activity Name: ${activity_name} \t Description: ${work_descripton}"
    }
}

特定问题密钥的预期 o/p,假设 'TST-3' 是 -


工作时间 |工作日期 |工作日期时间 |用户名 |记者 |


2.0 | 2014-01-01 | 2014-01-01 00:00:00 |管理员 |管理员 |


| 2014-01-02 | 2014-01-02 00:00:00 | admin | admin |

0.25| 2014-01-02 | 2014-01-02 10:33:00 |管理员 |管理员 |


2.0 | 2014-01-07 | 2014-01-02 12:03:00 |管理员 |管理员 |


如何在有序列表对象中为每个 issue_key 属性获取这些值。

【问题讨论】:

    标签: xml groovy xml-parsing xmlslurper


    【解决方案1】:

    作为解决您的问题的一种快速且可中继的方法,我建议您创建一个工厂方法,它将通过问题键为您提供初始化 Worklog 实例。

    在这种情况下,您将能够像您一样处理 xml,只需稍作更改。以下是处理工作日志的代码草稿。

    def worklogs = [:]
    def createWorklog(String id) {
       if (!worklogs.containsKey(id))
         worklogs[id] = new Worklog()
       return worklogs[id]
    }
    
    worklogs.worklog.each {node ->
        wklog = createWorklog(node.issue_key); // creates, or give created, and save it to list.
    
        // It don't know, what do you want to do with different dates or usernames.
        // If you want, you can have a list of them, and add value to list here, or consolidate whole change structures to list.
        wklog.hours += node.hours // aggregate hours.
    }
    

    【讨论】:

    • 谢谢。很抱歉,我对如何在 groovy 脚本中进行操作一无所知。如何将具有类似 issue_key 属性的详细信息工作日志节点存储在一个列表中,例如 TST-3 以排序顺序,即为问题和其他工作日志节点输入工作日志的顺序另一个列表。能否请您进一步说明一下。
    【解决方案2】:

    或者您可以定义一个plus 方法来添加Worklog 实例:

    @groovy.transform.Canonical
    @groovy.transform.ToString
    class Worklog
    {
        String issue_key
        Double hours
        String work_date
        String work_date_time
        String username
        String activity_name
        String work_description
        String reporter
    
        Worklog plus( Worklog w ) {
            new Worklog( issue_key,
                         hours + w.hours,
                         work_date,
                         work_date_time,
                         username,
                         activity_name,
                         work_description,
                         reporter )
        }
    }
    

    然后解析 xml,将条目按issue_key 分组,并将分组添加到单个条目中:

    def log = new XmlSlurper().parse( xmlFile )
                              .worklog
                              .collect { w ->
                                  new Worklog( w.issue_key.text(),
                                               w.hours.text() ? w.hours.text().toDouble() : 0,
                                               w.work_date.text(),
                                               w.work_date_time.text(),
                                               w.username.text(),
                                               w.activity_name.text(),
                                               w.work_description.text(),
                                               w.reporter.text() )
                              }
                              .groupBy { it.issue_key }
                              .values()*.inject { a, b -> a + b }
    

    【讨论】:

    • 谢谢蒂姆。我不想添加具有相同 issue_key 属性值的工作日志节点的小时数。我想将这些工作日志节点存储在一个集合中。
    【解决方案3】:

    我从 soapui 中尝试了以下操作,创建了新的 groovy 步骤并添加了以下代码,

    短版:

    def 出版书籍 = 新 XmlSlurper().parse('http://xyz:8003/myflow/api/books?expanded=true')

    log.info publishbooks.publishJob[0].jobName

    详细版本:

    //Written by Raja.
    // This code will parse the uri - http://xyz:8003/flow/api/jobs?expanded=true
    // and iterate through publishJob nodes and gets the jobid relavant to jobname we added.
    
    def publishJobs = new XmlSlurper().parse('http://xyz:8003/flow/api/jobs?expanded=true')
    String TSjobname = testRunner.testCase.testSuite.getPropertyValue('jobname')
    
    publishJobs.publishJob.findAll 
    
    { it.jobName == TSjobname }.each { 
          String id = it.@id
          testRunner.testCase.testSuite.setPropertyValue( "jobid", id  )
    log.info id;
    }
    

    uri 中的 XML 内容 - http://xyz:8003/myflow/api/books?expanded=true

    <PublishJobs>
        <publishJob id="248" xlink:href="http://xyz:8003/myflow/api/books/248">
            <completedTasksCount>196</completedTasksCount>
            <tasksCount>196</tasksCount>
            <generateArchive>false</generateArchive>
            <jobName>11111</jobName>
            <priority>10</priority>
            <status>FINISHED</status>
        </publishJob>
        <publishJob id="250" xlink:href="http://xyz:8003/myflow/api/books/250">
            <completedTasksCount>51</completedTasksCount>
            <tasksCount>51</tasksCount>
            <generateArchive>false</generateArchive>
            <jobName>44444</jobName>
            <priority>10</priority>
            <status>FINISHED</status>
        </publishJob>
    </PublishJobs>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多