Parse XML using Groovy and XmlSlurper and iterate the tags

Naren picture Naren · Feb 10, 2014 · Viewed 13.6k times · Source

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.

Answer

Seagull picture Seagull · Feb 10, 2014

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