0

When parsing an attribute, the slurper sets an empty string when an attribute is not found.

For e.g., car.setOwner(node.@owner.text());

In the above code, if the owner attribute is not found, then the slurper sets a blank string ("").

In my case, I'd rather leave it as null than setting an empty string.

Is it possible to configure the Slurper not to do this?

saravana_pc
  • 2,607
  • 11
  • 42
  • 66

2 Answers2

3

You could do

car.setOwner(node.@owner.text() ?: null)
tim_yates
  • 167,322
  • 27
  • 342
  • 338
1

If we distinguish between configure and using the Meta Object Protocol (MOP), then we can state that it is not possible to configure XmlSlurper as you describe, but it is possible to use the MOP.

For configure, note the following:

def node = new XmlSlurper().parseText('<car>No Owner</car>' )

def attr = node.@owner
assert groovy.util.slurpersupport.Attributes == attr.getClass()

If you look at the code for Attributes.text() (in this case, Groovy 2.2.2), it is clear that this cannot be configured to return null.

For MOP, we can capture the original Attributes.text() method and then override it:

import groovy.util.slurpersupport.*

def originalText = Attributes.metaClass.getMetaMethod("text")

Attributes.metaClass.text = { ->
    def result = originalText.invoke(delegate)
    if (result.isEmpty()) {
        result = null
    }
    result
}

// no owner
def node = new XmlSlurper().parseText('<car>No Owner</car>')
def attr = node.@owner
assert null == attr.text()

// with owner
node = new XmlSlurper().parseText('<car owner="codetojoy"></car>')
attr = node.@owner
assert "codetojoy" == attr.text()
Michael Easter
  • 23,733
  • 7
  • 76
  • 107
  • Great, thanks. I'd like this functionality throughout the project (i.e. across many groovy classes). Do I need to place the above code in a base class that all other groovy classes extend? Or, is there any other option? – saravana_pc May 28 '14 at 06:30
  • 1
    Here is the doc on the ExpandoMetaClass - http://groovy.codehaus.org/ExpandoMetaClass . Your comment question is too broad to answer here. (e.g. is this a webapp? simple script? etc). Be warned that MOP stuff is amazingly powerful, and with it that old chestnut about concomitant responsibility. – Michael Easter May 28 '14 at 09:54
  • Thanks for the reply. We've a grails application, so I'm a bit confused where this code should be placed. – saravana_pc May 28 '14 at 10:09