GINA之XmlParser和XmlSlurper异同

GINA:Groovy In Action
    Groovy的Document中只是介绍了XmlParser和XmlSlurper常用的用法,而且给你的感觉他俩孪生兄弟,给你相似的同时也给你疑惑 :) 还好在GIA中还有比较好的解释。
    先来看看他们的相同之处。[list]
[*]构造方法都是一模一样的,从缺省的构造到自定义的reader,parser等完全的一样
[*]解析XML的parse/parseText方法参数也完全的一致,当然了返回结果类型是不一样的 :)
[*]返回结果类型虽然不一样,但是他们处理GPath的语法却是那么一致
[/list]其实,处理XML我们比较关注的还是处理Xml的过程,也就是parser的返回结果,可喜的是groovy.util.Node(XmlParser)和GPathResult(XmlSlurper)对GPath的支持都很好,以下简单罗列一下他们常用的共同的方法:[list]
[*]name() 返回值:Node->Object,GPathResult->String
[*]text() 返回值:String
[*]toString() 返回值:String
[*]parent() 返回值:Node->Node,GPathResult->GPathResult,快捷方式:'[b][color=red]..[/color][/b]'
[*]children() 返回值:Node->List,GPathResult->GPathResult,快捷方式:'[b][color=red]*[/color][/b]'
[*]attributes() 返回值:Map,在GPathResult中并不存在此方法,但是当是节点类型时候会有此方法(实际上还是调用Node的attributes)
[*]iterator() 返回值:Iterator
[*]depthFirst() 返回值:Node->List,GPathResult->Iterator,快捷方式:'[b][color=red]**[/color][/b]'
[*]breadthFirst() 返回值:Node->List,GPathResult->Iterator
[/list]此外对XML元素和属性的操作也是同样的一致,如下:[list]
[*]['elementName']或.elementName,通过名称访问子元素
[*][index],通过下标访问子元素
[*]['@attributeName']或.'@attributeName',访问属性,GPathResult也可以将引号去掉,直接用.@attributeName访问
[/list]
    罗嗦了这么多,接下来,让我们实践一下吧 :D
def CAR_RECORDS = '''
<records>
<car name='HSV Maloo' make='Holden' year='2006'>
<country>Australia</country>
<record type='speed'>Production Pickup Truck with speed of 271kph</record>
</car>
<car name='P50' make='Peel' year='1962'>
<country>Isle of Man</country>
<record type='size'>Smallest Street-Legal Car at 99cm wide and 59 kg in weight</record>
</car>
</records>
'''
def parserRoot = new XmlParser().parseText(CAR_RECORDS)
def slurperRoot = new XmlSlurper().parseText(CAR_RECORDS)
assert 'records'==parserRoot.name()
assert 'records'==slurperRoot.name()
assert 2==parserRoot.car.size()
assert 2==slurperRoot.car.size()
assert 'P50'==parserRoot.car[1].'@name'
//assert 'P50'==slurperRoot.car[1].@name //error a bug?
assert 'P50'==slurperRoot.car[1].@name.text()
assert slurperRoot.car[1].@name=='P50'
assert slurperRoot.car.any{ it.@name == 'P50' }


    说了那么多行同点,不禁要问既生“XmlParser”又生“XmlSlurper”,何必呢 :),马上我们来看不同之处。前面也可以看到,它们最大的不同就是parse的返回类型不同,因此主要是groovy.util.Node(XmlParser)和GPathResult(XmlSlurper)的不同。
    groovy.util.Node是以list的形式来表述GPath的,因此Node在可显性有着明显的优势,比如toString可以直接看到结果,可以直接print,可以在原处修改等等。那缺点呢?显而易见,因为用list来表述,因此也需要额外的内存空间来存储,这在Xml内容小的时候,没啥问题,可一旦处理大量的Xml时,要慎之!慎之!罗列一些Node特有的方法[list]
[*]Object value()
[*]void setValue(Object value)
[*]Object attribute(Object key)
[*]NodeList getAt(QName name)
[*]void print(PrintWriter out)
[/list]
    再来看看GPathResult,它没有使用list来处理GPath,而是采用iterators方式,因此没有了额外空间消耗,可是如果要访问最后一个node时候,可要费点时间了 :D 罗列一些GPathResult特有的方法[list]
[*]GPathResult parents()
[*]GPathResult declareNamespace(Map newNamespaceMapping)
[*]List list()
[*]int size()
[*]GPathResult find(Closure closure)
[*]GPathResult findAll(Closure closure)
[/list]
    总之,两种方式各有优缺点,每个人可以根据实际的情况灵活应用,另外Grails的plugin的doWithWebDescriptor参数就是XmlSlurper。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值