Here is another way to achieve the same.
Note that user can easily change / add the additional and
condition(s) easily by adding as shown below
def queryData = [[<element>, <operator>, <element value>], [<element>, <operator>, <element value>], ...]
Operator can be one the below:
EQ
for equals to
LE
for less than or equals to
GE
for greater than or equals to
GT
for greater than
LT
for less than
NE
for not equals to
For example:
def queryData = [['year','EQ', '2003'], ['price', 'LE', '39.95']]
Basically it creates a closure
based on the queryData
and pass it to findAll
.
getQuery
closure builds the query to the above list of condition as
{ it -> it.year.text() == '2003' && it.price.text() <= '39.95' }
I felt that it would be easier for some new folks trying groovy to use above list instead of closure as above which is built dynamically.
Here is the script:
def xml = """<stores> <bookstore name="Store A">
<employee>
<id>546343</id>
<name>Dustin Brown</name>
</employee>
<employee>
<id>547547</id>
<name>Lisa Danton</name>
</employee>
<book category="cooking">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="children">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="web">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
</bookstore>
<bookstore name="Store B">
</bookstore>
</stores>"""
//You may just add additional conditions into below list
def queryData = [['year','EQ', '2003'], ['price', 'LE', '39.95']]
enum Operator {
EQ('=='), LE('<='), GE('>='), GT('>'), LT('<'), NE('!=')
def value
Operator(String value){
this.value = value
}
def getValue(){
value
}
}
def getQuery = { list ->
def sb = new StringBuffer('{ it -> ')
list.eachWithIndex { sublist, index ->
index == 0 ?: sb.append(' && ')
Operator operator = sublist[1]
sb.append("it.${sublist[0]}.text() ${operator.value} '${sublist[2]}'")
}
def query = sb.append(' }').toString()
println "Query formed is : ${query}"
def sh = new GroovyShell()
sh.evaluate(query)
}
def getBooks = { stores, closure ->
stores.'**'.findAll { closure(it) } ?: 'Could not find matching book'
}
def stores = new XmlSlurper().parseText(xml)
def result = getBooks(stores, getQuery(queryData))
println result
You may quickly try Demo
Also note that it is currently does only and
of conditions, does not support or
.