2017-02-14 21 views
1

GroovyのXMLSlurperで特定のノードを見つける必要があります。条件は、子ノードのテキスト/値が一致しなければならないことです。次の例では、年が '2003'、価格が'95 .95 'のブックノードを検索したいと考えています。考えるGroovy XMLSlurper - 特定のノードを検索する

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

答えて

2

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

を次にここ

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

は、同じことを達成するための別の方法です。ユーザが容易容易追加and条件(複数可)を追加/変更することができる

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

以下のように追加することによって、オペレータは、一以下であることができる:と等しいため

  • EQ
  • LE以下の場合は
  • GEより大きいまたは等しい場合ない未満
  • NEためのより大きい
  • LTため
  • GT
  • には、例えば

に等しい:

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

基本的にはqueryDataおよびパスに基づいclosureを作成しますそれはfindAllになります。

getQuery閉鎖

{ it -> it.year.text() == '2003' && it.price.text() <= '39.95' } 
私は構築され、上記のようにいくつかの新しい人々が代わりにクロージャのリストの上に使用するグルーヴィーしようとするために容易になるだろうと感じていた

などの条件を上記のリストにクエリを作成します動的にDemo

またorをサポートしていません、それは現在だけand条件のないことに注意し

​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 

あなたはすぐに試すことがあります。ここでは

はスクリプトです。

関連する問題