Search code examples
groovytypesxmlslurper

GPathResult field namesapceTagHints has type Map<String, String> but getClass() returns NodeChildren


I think I am going mad. I am using Groovy for handling xml files and wanted to write a little helper class to help myself get nodes by name in a typed way. While doing this I created a class extending NodeChild:

class XmlNode extends NodeChild {

    XmlNode(NodeChild nodeChild) {
        super(nodeChild[0] as Node, nodeChild.parent, nodeChild.namespacePrefix, nodeChild.namespaceTagHints)
    }

    // helpful methods
}

But I can't instantiate this class without getting this error:

org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object '' with class 'groovy.xml.slurpersupport.NodeChildren' to class 'java.util.Map'

So I just had to check. Apparently:

println(nodeChild.namespaceTagHints.getClass())

returns:

class groovy.xml.slurpersupport.NodeChildren

But namespaceTagHints is supposed to be of type Map<String, String> at least according to the Apache Groovy GitHub project.

Can anyone explain what is going on? Or am I just completely missing something?


Solution

  • as @tim_yates mentioned nodeChild.namespaceTagHints evaluated through nodeChild.getProperty("namespaceTagHints")

    and according to the code it tries to get child xml nodes with corresponding name GPathResult.java#L118

    as workaround instead of nodeChild.namespaceTagHints you can use:

    NodeChild.metaClass.getProperty(nodeChild, 'namespaceTagHints')
    

    same for nodeChild.parent and nodeChild.namespacePrefix