diff --git a/src/main/groovy/com/bloidonia/groovy/extensions/NodeChildExtensionMethods.groovy b/src/main/groovy/com/bloidonia/groovy/extensions/NodeChildExtensionMethods.groovy index abe3790..89b4657 100644 --- a/src/main/groovy/com/bloidonia/groovy/extensions/NodeChildExtensionMethods.groovy +++ b/src/main/groovy/com/bloidonia/groovy/extensions/NodeChildExtensionMethods.groovy @@ -23,15 +23,24 @@ import groovy.util.slurpersupport.NodeChild * Date: 11/20/12 */ class NodeChildExtensionMethods { - static Map toMap( NodeChild self ) { - toMap( self, '_children' ) + static Map toMap( NodeChild self, def m=[:] ) { + m[self.name()] = self.attributes() ? [*:self.attributes()] : self.text() + if (self.children().size()) { + self.children().each { c -> + c.toMap().inject(m[self.name()]) { r, k, v -> + if (r instanceof Map) { + if (r[k] && (r[k] instanceof List)) { + m[self.name()][k] << v + } else if (r[k] && !(r[k] instanceof List)) { + m[self.name()][k] = [r[k]] << v + } else { + m[self.name()][k] = v + } + } + else { m[self.name()]=[:].with{it[k]=v;it} } + } + } + } + m } - - static Map toMap( NodeChild self, String childKey ) { - [ - (self.name()): [ *:self.attributes() ] << - ( self.children().size() ? [ (childKey): self.children().collect { it.toMap( childKey ) } ] - : [:] ) - ] - } -} +} \ No newline at end of file diff --git a/src/test/groovy/tests/NodeToMapTests.groovy b/src/test/groovy/tests/NodeToMapTests.groovy index d41f22e..c2c5a31 100644 --- a/src/test/groovy/tests/NodeToMapTests.groovy +++ b/src/test/groovy/tests/NodeToMapTests.groovy @@ -23,49 +23,51 @@ import spock.lang.Specification * Date: 11/20/12 */ class NodeToMapTests extends Specification { - def 'check xml string to node to map coercion with children'() { + def 'check xml to map coercion with children'() { given: def xml = ''' | | |'''.stripMargin() - def map = new XmlSlurper().parseText( xml ).toMap() + def map = _getMap(xml) expect: map instanceof Map - map.dan._children.size() == 2 - map.dan._children.key[1].value == 'val2' + map.dan.key.size() == 2 + map.dan.key[1].value == 'val2' } - def 'check xml string to node to map coercion with children and specified childKey'() { + def 'check xml to map coercion'() { given: - def xml = ''' - | - | - |'''.stripMargin() - def map = new XmlSlurper().parseText( xml ).toMap( 'kids' ) + def xml = '' + def map = _getMap(xml) expect: - map instanceof Map - map.dan.kids.size() == 2 - map.dan.kids.key[1].value == 'val2' + map == [dan: [value: 'a', subnode: [item: [value: 'a']]]] } - def 'check map value'() { + def 'check nested without attrs'() { given: - def xmlstr = '' - def xml = new XmlSlurper().parseText( xmlstr ) - def map = xml.toMap() + def xml = 'maybe' + def map = _getMap(xml) + expect: - map == [dan:[value:'a',_children:[[subnode:[_children:[[item:[value:'a']]]]]]]] + map == [dan: [ cool: "maybe" ] ] } - def 'check map value with childKey'() { + def 'test angry schema design'() { given: - def xmlstr = '' - def xml = new XmlSlurper().parseText( xmlstr ) - def map = xml.toMap( 'kids' ) + def xml = ''' + | maybe + | + '''.stripMargin() + def map = _getMap(xml) + expect: - map == [dan:[value:'a',kids:[[subnode:[kids:[[item:[value:'a']]]]]]]] + map == [dan: [cool: ['yes', 'maybe']]] + } + + def _getMap(xml) { + new XmlSlurper().parseText(xml).toMap() } }