Question

I am able to parse XML through HTTP URL by using Groovy and XmlSlurper and output the values associated to tags. Below is the generated sample XML page.

<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>

However, in my XML I need to traverse through my XML and look for the issue_key tags having same value. If there are multiple issue_key tags with same value, as in here "TST-3", then I want to collect and consolidate the values associated with hour work_date, work_date_time, username, activity_name, work_description, parent_key, reporter tags for this single issue_key tag and then output it in the same order in which it was generated along with the other tags having different issue_key values.

Sorry for being a completee noob to Groovy and XmlSlurper. But can anybody let me know how to go about it. Also, below is my Groovy code to get the attributes from the XML.

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}"
    }
}

And the expected o/p for a particular issue key,let's say 'TST-3' is -


Hours Worked | Work Date | Work Date Time | Username | Reporter |


2.0 | 2014-01-01 | 2014-01-01 00:00:00 | admin | admin |


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

0.25| 2014-01-02 | 2014-01-02 10:33:00 | admin | admin |


2.0 | 2014-01-07 | 2014-01-02 12:03:00 | admin | admin |


How can I get these values in ordered list object for every issue_key attribute.

Was it helpful?

Solution

As a quick and relayable way to solve your problem I suggest you to create a factory method, that will give you initialised Worklog instance by issue key.

In that case, you will be able process xml same as you do, with minor changes. Below is a draft of code, to process worklogs.

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.
}

OTHER TIPS

Or you could define a plus method to add Worklog instances:

@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 )
    }
}

And then parse the xml, group the entries by issue_key and add the groups into a single entry:

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 }

I tried the below from soapui, created new groovy step and added below code,

Shorter version:

def publishbooks = new XmlSlurper().parse('http://xyz:8003/myflow/api/books?expanded=true')

log.info publishbooks.publishJob[0].jobName

Detailed Version:

//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;
}

XML Content inside the uri - http://xyz:8003/myflow/api/books?expanded=true is

<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>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top