Groovy and Grails Recipes翻译之旅——面向对象的Groovy(12)

4.12.           什么是GPaths

GPath是一种识别查询结构化数据的表达式。GPath Groovy来说相对于XPathXML的作用,它能帮助您遍历任何简单Java对象(POJO)或XML文件的结构。GPath的强大功能在于它使您使用最小的代码来完成复杂的类层次结构的查询。

举个简单例子,您可使用GPath打印String类的所有的方法,如:

"".class.methods.name.sort()

 

具体结果如下:

["charAt", "codePointAt", "codePointBefore", "codePointCount", "compareTo", "compareTo", "compareToIgnoreCase", "concat", "contains", "contentEquals", "contentEquals", "copyValueOf", "copyValueOf", "endsWith", "equals", "equalsIgnoreCase", "format", "format", "getBytes", "getBytes", "getBytes", "getBytes", "getChars", "getClass", "hashCode", "indexOf", "indexOf", "indexOf", "indexOf", "intern", "isEmpty", "lastIndexOf", "lastIndexOf", "lastIndexOf", "lastIndexOf", "length", "matches", "notify", "notifyAll", "offsetByCodePoints", "regionMatches", "regionMatches", "replace", "replace", "replaceAll", "replaceFirst", "split", "split", "startsWith", "startsWith", "subSequence", "substring", "substring", "toCharArray", "toLowerCase", "toLowerCase", "toString", "toUpperCase", "toUpperCase", "trim", "valueOf", "valueOf", "valueOf", "valueOf", "valueOf", "valueOf", "valueOf", "valueOf", "valueOf", "wait", "wait", "wait"]

接下来,将给出一个更广泛的例子。假设您有BookBookSales类,两者之间是一对一的关系,如清单4.30

清单 4.30 BookSalesBook

class BookSales{

  int numSold   

  Book book

  int sales(){

    return book.price * numSold

  }

}

class Book{

  int price

  float authorRoyaltyFee

  String title

}

 

同时,还有Author类,它与BookSales存在一对多的关系,如清单4.31所示。

 

例程4.31 Author

class Author{

  String name

  List bookSales

  int totalEarnings(){

    def total = 0

    bookSales.each{

      total += it.sales() * it.book.authorRoyaltyFee

    }

  return total

  }

}

 

紧接着创建一些BookBookSales对象,并赋值于相应的Author对象:

 

def book1 = new Book(title:"Groovy Grails Recipes", price:44, authorRoyaltyFee:0.1)

def book2 = new Book(title:"Groovy and Grails Rock", price:35, authorRoyaltyFee:0.2)

def bookSales1 = new BookSales(numSold : 5000, book: book1)

def bookSales2 = new BookSales(numSold : 1000, book: book2)

def authors = [

        new Author(name:"Bashar", bookSales: [bookSales1, bookSales2]),

        new Author(name:"Sami", bookSales:[bookSales2])]

 

正是由于GPath的强大功能,查询对象图变得异常简单。如查询每个作者的总收入,您可使用以下代码:

assert authors*.totalEarnings() == [29000, 7000]

 

注意到该清单使用了展开操作符*.spread operator)。该操作符用来在一个集合对象的所有元素上执行一个动作的,而不是集合本身。

查询销售额达到200,000美元的所有书名,如:

authors.bookSales.each{

    println it.grep{it.sales() > 200000}.book.title

}

Groovy 代码就是如此简单!想象一下,如果使用 Java 遍历对象图,您则需编写多行 Java 代码才能实现。

你可能感兴趣的:(数据结构,xml,grails,groovy)