2

Given xml:

<d>
    <r1 dt="2011-06-10">
        <r11 dt="2012-07-10" />
        <r12 rdt="2011-10-11">
            <r121 dt="2010-05-13" />
        </r12>
    </r1>
    <r2>
        <r21 dt="2011-10-10"><n2 ddt="2012-11-31"/>dt</r21>
        <r22 dt="2013-07-10"><n2 ddt="2013-06-31"/>dt</r22>
        <r23 dt="2014-06-10"><n2 ddt="2014-03-31"/>dt</r23>
        <r24 dt="2015-06-10"><n2 ddt="2011-10-31"/>dt</r24>
    </r2>
</d>

I need to find value among attributes dt, rdt and ddt that has maximum date using Groovy XmlSlurper. In the given example it will be 2015-06-10. Suppose xml tree structure and deep is unknown (varies). Is it possible to do it using onliner, or should I do some iterations in my code?

M.Void
  • 2,764
  • 2
  • 29
  • 44
lospejos
  • 1,976
  • 3
  • 19
  • 35

1 Answers1

2

Assuming s is string containing xml:

def x = new XmlSlurper().parseText(s)

Then this will get you a list of all dt attribute values

def list = x.depthFirst().findAll { it.@dt != "" }​.collect {it.@dt}​​​

you can use a similar bit of code to get lists of all rdt and ddt. Put em all into a single list and then just get max you can do:

list.max { a, b -> 
    new Date().parse("yyyy-MM-dd", a.toString()) <=> new Date().parse("yyyy-MM-dd", b.toString())
} ​
OsaSoft
  • 589
  • 5
  • 19
  • You probably meant `list.max` when written `l.max`? Anyway thanks, everything worked like a charm. – lospejos Aug 02 '16 at 13:35
  • @lospejos haha yeah, I was using one letter vars in groovy console for testing, then decided to rename them for the answer. Guess I missed that one, cheers! – OsaSoft Aug 02 '16 at 13:42
  • Could you please provide code in case if I need not just a maximum date value (not plain string), but reference to a parent node that contains this maximum date value attribute? – lospejos Aug 02 '16 at 14:10
  • 1
    Well the list here will be a list of instances of the slurpers attribute class (http://docs.groovy-lang.org/latest/html/gapi/groovy/util/slurpersupport/Attributes.html). So if you wanted the parent to lets say the first one, you could do `list[0].parents()`. – OsaSoft Aug 02 '16 at 14:16
  • Unfortunately, groovy.lang.GroovyRuntimeException: parents() not implemented yet. This is also present here: http://docs.groovy-lang.org/latest/html/api/groovy/util/slurpersupport/Attributes.html#parents() – lospejos Aug 02 '16 at 14:32
  • 1
    Oh wow. Well `parent()` seems to work. `list[0].parent()​.name()​` gives me `r1` – OsaSoft Aug 02 '16 at 14:45
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/118927/discussion-between-lospejos-and-osasoft). – lospejos Aug 02 '16 at 15:10