How can I check for the existence of an element with Groovy's XmlSlurper?
Asked Answered
A

2

34

I'm trying to determine whether an XML element exists with Groovy's XmlSlurper. Is there a way to do this? For example:

<foo>
  <bar/>
</foo>

How do I check whether the bar element exists?

Assize answered 26/1, 2009 at 16:39 Comment(0)
R
42

The API is a little screwy, but I think that there are a couple of better ways to look for children. What you're getting when you ask for "xml.bar" (which exists) or "xml.quux" which doesn't, is a groovy.util.slurpersupport.NodeChildren object. Basically a collection of nodes meeting the criteria that you asked for.

One way to see if a particular node exists is to check for the size of the NodeChildren is the expected size:

def text = "<foo><bar/></foo>"
def xml = new XmlSlurper().parseText(text)
assert 1 == xml.bar.size()
assert 0 == xml.quux.size()

Another way would be to use the find method and see if the name of the node that gets returned (unfortunately something is always returned), is the one you were expecting:

def text = "<foo><bar/></foo>"
def xml = new XmlSlurper().parseText(text)
assert ("bar" == xml.children().find( {it.name() == "bar"})?.name())
assert ("quux" != xml.children().find( {it.name() == "quux"})?.name())
Rollet answered 27/1, 2009 at 3:40 Comment(1)
As of Groovy 1.8.6 at least, GPathResult has a method boolean isEmpty() which is implemented as return size() == 0;Borden
A
19

The isEmpty method on GPathResult works.

def text = "<foo><bar/></foo>"
def xml = new XmlSlurper().parseText(text)
assert false == xml.bar.isEmpty()

This bothers me, because the bar element is empty - it doesn't have a body. But I suppose the GPathResult isn't empty, so maybe this makes sense.

Assize answered 26/1, 2009 at 16:53 Comment(3)
I like the size() method better as I think it's a little less confusing, but the reason isEmpty is returning false is because it's talking about the NodeChildren collection that gets returned. It's not empty because there is a "bar", and isEmpty would be true for xml.quux because there isn't a quuxRollet
I understand, and I think you're right - the size() method is a little less confusing. Thanks again for your answer, Ted.Assize
The issue is that the javadoc of isEmpty doesn't defines the "empty" semantics. It seems the isEmpty is not checked on the element contents but on the element container, like xml.bar is the container of all bar elements in xml, so isEmpty will be false if there is one bar in the container.Breland

© 2022 - 2024 — McMap. All rights reserved.