简体   繁体   中英

Groovy: Using Closure to create and return Map Elements

I am importing an XML and then creating a list of objects based on the information from the XML.

This is a sample of my XML:

<DCUniverse>
   <SuperHeroes>
       <SuperHero>
           <SuperHeroName>SuperMan</SuperHeroName>
           <SuperHeroDesc>Surviver of Krypton; Son of Jor-el</SuperHeroDesc>
           <SuperHeroCode>SM</SuperHeroCode>
           <SuperHeroAttrs>
               <SuperHeroAttr Name="Strength">All</SuperHeroAttr>
               <SuperHeroAttr Name="Weakness">Kryptonite</SuperHeroAttr>
               <SuperHeroAttr Name="AlterEgo">Clark Kent</SuperHeroAttr>
           </SuperHeroAttrs>
       </SuperHero>
       <SuperHero>
           <SuperHeroName>Batman</SuperHeroName>
           <SuperHeroDesc>The Dark Knight of Gothom City</SuperHeroDesc>
           <SuperHeroCode>BM</SuperHeroCode>
           <SuperHeroAttrs>
               <SuperHeroAttr Name="Strength">Intellect</SuperHeroAttr>
               <SuperHeroAttr Name="Weakness">Bullets</SuperHeroAttr>
               <SuperHeroAttr Name="AlterEgo">Bruce Wayne</SuperHeroAttr>
           </SuperHeroAttrs>
       </SuperHero>
   </SuperHeroes>
<DCUniverse>

Here is an example of the groovy script that I am running to create the objects:

class Hero{
    def SuperHeroName
    def SuperHeroDesc
    def SuperHeroCode
    def SuperHeroAttrLst = [:]
    Hero(String name, String desc, String code, attrLst){
        this.SuperHeroName=name
        this.SuperHeroDesc=desc
        this.SuperHeroCode=code
        this.SuperHeroAttrLst.putAll(attrLst)
    }
}
def heroList = []

def heroDoc = new XmlParser().parse('dossier.xml')

heroDoc.SuperHeroes.each{ faction ->
    faction.SuperHero.each{ hero ->
        heroList += new Hero(   hero.SuperHeroName.text(),
                                hero.SuperHeroDesc.text(),
                                hero.SuperHeroCode.text(),
                                hero.SuperHeroAttrs.SuperHeroAttr.each{ attr ->
                                    return  [ (attr.'@Name') : (attr.text()) ]
                                })
    }
}

When I run the above code, I get the following error:

java.lang.ClassCastException: groovy.util.Node cannot be cast to java.util.Map$Entry

I have a strong feeling that it has something to do with the last variable that the closure is trying to send to Hero Class Constructor. Commenting out

this.SuperHeroAttrLst.putAll(attrLst)

in the Hero Constructor allows the script to at least parse correctly. What I am trying to do is create a class based on the XML and place it in the list like:

heroList += new Hero('Batman',
 'The Dark Knight of Gothom City',
 'BM',
 ['Strength':'Intellect', 'Weakness':'Bullets', 'AlterEgo':'Bruce Wayne'] )

However, my variable typing is incorrect and I dont know enough about Groovy's (or Java's) syntax to make it work.

Any help that can be provided would be much appreciated. Thank you for your time.

I think you should change hero.SuperHeroAttrs.SuperHeroAttr.each{ //blah blah to:

hero.SuperHeroAttrs.inject([:]) { attributes, attr ->
    attributes[attr.'@Name'] = attr.text()
    return attributes
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM