Groovy-Gpath总结

2017-01-16 20:13

Groovy Gpath

两个类之间的访问

class Address{
    String prov
    String city
}

class Person{
    String id
    String name
    Address addr // 关联地址类
}

//Gpath来操作它们
def addr = new Address(prov:'Hubei',city:'Xiaogan')
def person = new Person(id:123,name:'Wallace',addr:addr)
println person.name
println person.addr.city

值得注意的是,上面的嵌套访问并不是安全的。请看下面的例子:

 def person = new Person(id:123,name:'Wallace')  
 println person.addr.city
  • 这样的访问就会报空指针的错误。为了解决这种空指针的错误,在Java语言中通常要做如下的非空判断:
if(person!=null&&person.addr!=null){
     println person.addr.city
  }
  • groovy处理简单很多,只要用?.操作即可,它的结果是如果Gpath访问的对象存在,则返回结果;否则返回null
def person = new Person(id:123,name:'Wallace')
println person?.addr?.city

对xml的操作

def text = """
            <persons>
               <person sex='male'>
                   <id>1</id>
                   <name>Tom</name>
               </person>
               <person sex='female'>
                  <id>2</id>
                  <name>Alice</name>
               </person>
           </persons>
      """

def node = new XmlSlurper().parseText(text)

node.person.each{
    println it.name
}

Gpath对XML的访问不会存在空指针的情况,而会直接返回null。请看下面的例子:

println node.p.x

访问GroovyBean

用Gpath访问GroovyBean对象的属性并不是直接访问该属性,而是通过“set”和“get”方法进行的

class Person
{
    String id
    String name
    Address addr

    def getName()
    {
       return 'Tom'
    }
}

在上面的“Person”类中,我们自己定义了“getName”方法,让它永远返回“Tom”,下面,我们使用Gpath来测试它:

def person = new Person(id:123,name:'Wallace')
println person.name

运行结果为:
Tom

由于我们在“person”对象的定义中设置了“name”属性的值为“Wallace”,很明显,“person”对象的“name”属性值为“Wallace”,但我们使用“person.name”访问的返回值只能是“Tom”,因为方法“getName”永远返回“Tom”。
当然,我们也有办法访问属性的真实值,这就是使用.@操作符。请看下面的例子

def person = new Person(id:123,name:'Wallace')
println person.name 
println person.@name

运行结果为:
Tom
Wallace

“.@”操作xml

通过Gpath访问XML的时候,“.@”操作符也有它自己的用途。请看下面的例子:

 def text = """
            <persons>
               <person sex='male'>
                   <id>1</id>
                   <name>Tom</name>
               </person>
               <person sex='female'>
                  <id>2</id>
                  <name>Alice</name>
               </person>
           </persons>
      """

      def node = new XmlSlurper().parseText(text)

      node.person.each{
         println it.@sex
  }

运行结果为:
male
female

可以看出,使用“.@”操作符可以访问一个节点的属性。

查看原文

Groovy的展开操作符(Spread Operator)*.*

*. 操作符称之为:spread-dot操作,即“展开(点)”操作。比如

list*.member

list.collect{ item -> item?.member } 

上面的是等效的。此处member可以是属性,也可以是get/set方法,甚至是一般的方法。如下例:

class SpreadDotDemo { 
   def count 
}
def list = [new SpreadDotDemo(count:1),new SpreadDotDemo(count:2),new SpreadDotDemo(count:5) ] 
assert 8==list*.count.sum() 
assert 8==list.count.sum()//去掉*也可以的

“*.”也是安全解引用操作符(Safe Dereference Operator也称为提领运算符),用以避免NullPointerException。

def SpreadDotDemo demo
demo.count //将抛空指针异常
demo*.count //避免了null的检查,并返回null
  • 跟spead doc操作符相关的事spead操作(*),它可以看作是逗号分隔的list的下标操作符的逆操作
def getList(){ 
   return [1,2,3] 
}
def sum(a,b,c){ 
   return a + b + c 
}
assert 6 == sum(*list) 
def range = (1..3)
assert [0,1,2,3] == [0,*range]

相同的戏法同样可以应用在 map 上:

def map = [a:1,b:2]
assert [a:1, b:2, c:3] == [c:3, *:map]