Groovy中XmlParser和XmlSlurper异同

GINA:Groovy In Action  
Groovy的Document中只是介绍了XmlParser和XmlSlurper常用的用法,而且给你的感觉他俩孪生兄弟,给你相似的同时也给你疑惑 还好在GIA中还有比较好的解释。 
先来看看他们的相同之处。 其实,处理XML我们比较关注的还是处理Xml的过程,也就是parser的返回结果,可喜的是groovy.util.Node(XmlParser)和GPathResult(XmlSlurper)对GPath的支持都很好,以下简单罗 列一下他们常用的共同的方法: 此外对XML元素和属性的操作也是同样的一致,如下:
罗嗦了这么多,接下来,让我们实践一下吧
Java代 码  收藏代码
  1. def CAR_RECORDS = '''  
  2.     <records>  
  3.       <car name='HSV Maloo' make='Holden' year='2006'>  
  4.         <country>Australia</country>  
  5.         <record type='speed'>Production Pickup Truck with speed of 271kph</record>  
  6.       </car>  
  7.       <car name='P50' make='Peel' year='1962'>  
  8.         <country>Isle of Man</country>  
  9.         <record type='size'>Smallest Street-Legal Car at 99cm wide and 59 kg in weight</record>  
  10.       </car>  
  11.     </records>  
  12.   '''  
  13. def parserRoot = new XmlParser().parseText(CAR_RECORDS)  
  14. def slurperRoot = new XmlSlurper().parseText(CAR_RECORDS)  
  15. assert 'records'==parserRoot.name()  
  16. assert 'records'==slurperRoot.name()  
  17. assert 2==parserRoot.car.size()  
  18. assert 2==slurperRoot.car.size()  
  19. assert 'P50'==parserRoot.car[1].'@name'  
  20. //assert 'P50'==slurperRoot.car[1].@name //error a bug?  
  21. assert 'P50'==slurperRoot.car[1].@name.text()  
  22. assert slurperRoot.car[1].@name=='P50'  
  23. 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特有的方法
再来看看GPathResult,它没有使用list来处理GPath,而是采用iterators方式,因此没有了额外空间消耗,可是如果要访问最后一个node时候,可要费点时间了 罗列一些GPathResult特有的方法
总之,两种方式各有优缺点,每个人可以根据实际的情况灵活应用,另外Grails的plugin的doWithWebDescriptor参数就是XmlSlurper。