2017-02-14 15 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

가 동일한을 달성하는 또 다른 방법이다. 같음위한

  • EQ : 아래의 하나가 될 수

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

    조작 아래와 같이 사용자가 용이하게 추가함으로써 쉽게 변경/부가 and 조건 (들)을 추가 할 수

    참고

  • LE보다 작거나 같음 :
  • GE 이상 또는 같음

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

    기본적으로는 queryData 및 패스에 기초 closure 작성하지 미만

  • NE보다 큰
  • LT위한
  • GT에 예

같음 그것을 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 

당신은 신속하게 시도 할 수 있습니다 : 여기

는 스크립트입니다.