gpathresult groovy xml-parsing xmlslurper

gpathresult - Groovy XMLSlurper-búsqueda de nodo específico



xml-parsing (2)

Necesito encontrar un nodo específico con XMLSlurper de Groovy. La condición debe ser que el texto / valor de los nodos hijos tenga que coincidir. En el siguiente ejemplo, quiero buscar un nodo de libro donde el año es ''2003'' y el precio es ''39 .95 ''.

<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>


Aquí hay otra manera de lograr lo mismo.

Tenga en cuenta que el usuario puede cambiar / agregar fácilmente el adicional and condiciones fácilmente agregando como se muestra a continuación

def queryData = [[<element>, <operator>, <element value>], [<element>, <operator>, <element value>], ...]

El operador puede ser uno de los siguientes:

  • EQ para iguales a
  • LE por menos o igual a
  • GE para mayor o igual a
  • GT para mayor que
  • LT por menos de
  • NE para no es igual a

Por ejemplo:

def queryData = [[''year'',''EQ'', ''2003''], [''price'', ''LE'', ''39.95'']]

Básicamente, crea un closure basado en queryData y lo pasa a findAll .

getQuery cierre de getQuery construye la consulta a la lista de condiciones anterior como

{ it -> it.year.text() == ''2003'' && it.price.text() <= ''39.95'' }

Sentí que sería más fácil para algunos nuevos que intenten usar Groovy la lista anterior en lugar del cierre, como se explicó anteriormente, que está construida dinámicamente.

Aquí está el guión:

​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

Puede probar Demo rápidamente

También tenga en cuenta que actualmente solo hace and de condiciones, no admite or .


Dado:

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>''''''

Entonces

new XmlSlurper().parseText(xml).bookstore.book.findAll { it.year == ''2003'' && it.price == ''39.95'' }