第六章 gradle自动化构建系列文章 之 Groovy基础语法 - xml数据解析

第六章 gradle自动化构建系列文章 之 Groovy基础语法 - xml数据解析

< center>

查看 “Android自动化构建系列” 全部文章

1、XmlParser解析XML。

可以解析xml文件,也可以解析字符串。

	def persons = new XmlParser().parse("persons.xml")
  • 或者

      //定义xml
      xmlStr = """
      
      	
      		136124568
      		131254225
      	
      	
      		132595965
      		133256555
      	
      	
      		133455961
      		133289411
      	
      
      """
      def persons = new XmlParser().parseText(xmlStr)
    

(2) XmlParser直接使用节点名称来访问,通过@+属性名来访问节点属性值,使用text方法来访问内容值。

  • 输出persons 下的所有 person 节点

      println persons.person 
    
      输出结果:(得到一个person集合)
      
    
      [person[attributes={name=Mike, address=ShangHai}; value=[phone[attributes={}; value=[136124568]], phone[attributes={}; value=[131254225]]]], person[attributes={name=Lily, address=BeiJing}; value=[phone[attributes={}; value=[132595965]], phone[attributes={}; value=[133256555]]]], person[attributes={name=Jack, address=ShenZheng}; value=[phone[attributes={}; value=[133455961]], phone[attributes={}; value=[133289411]]]]]
    
  • 输出persons 下的第零个 person 个节点

      println persons.person[0]
    
      输出结果:(获取了person集合的第零个)
    
    
      person[attributes={name=Mike, address=ShangHai}; value=[phone[attributes={}; value=
      [136124568]], phone[attributes={}; value=[131254225]]]]
    
  • 输出persons 下的第零个 person 节点的 name 属性

      println persons.person[0].@name   		
    
      输出结果:(person集合第0个元素的name属性值)
      
      Mike
    
  • 输出persons 下的第零个 person 节点的 phone节点信息

      println persons.person[0].phone
    
    
      输出结果:(person集合第0个元素的 phone节点信息)
      
      [phone[attributes={}; value=[136124568]], phone[attributes={}; value=[131254225]]]
    
  • 输出persons 下的第零个 person 节点的内容值

      println persons.person[0].text()    	
    
      输出结果:(person集合第0个元素的下的所有节点内容)
    
      136124568131254225
    
  • 因为 println persons.person[0].phone 返回的是集合,根据集合的知识,所有我们可以转换输出的list

      println persons.person[0].phone.collect{it.text()}
    
    
      输出结果:(person集合第0个元素的下的所有节点内容的集合)
    
      [136124568, 131254225]
    
  • 输出 persons 下所有value

      println persons.person.text()
    
      输出结果:(person集合中所有的value)
    
      136124568131254225132595965133256555133455961133289411
    

总结

1.通过上面的案例可以看出在Groovy中可以直接使用 , 根节点.子节点【标】.子子节点【下标】.@属性名称的形式获取节点属性 ;

2.通过 根节点.子节点【标】.子子节点【下标】.text() 方法获取value

3.可以很groovy中 根节点.子节点 的形式简单高效的获取了我们希望得到的值

4.根节点.子节点得到的是一个集合

5.只有没有闭环标签的才是value


	136124568
	131254225

比如上面只有 136124568131254225 是value其他都不是

2. xml 文件的遍历

  • 数组,统计所有人的手机号,在原有的思维中我们这样遍历

      //定义xml
      xmlStr = """
      
      	
      		136124568
      		131254225
      	
      	
      		132595965
      		133256555
      	
      	
      		133455961
      		133289411
      	
      
      """
      def persons = new XmlParser().parseText(xmlStr)
      
      
      
      //循环遍历统计每个人的手机号
      
      def phonesList=[]
      
      persons.person.each{person->
          person.each{ number->
              phonesList.add(number.text())
          }
      }
      println phonesList.toListString()
    

其实现在有了groovy的支持我们可以这样遍历

#####1. 深度遍历,depthFirst() 可以使用 ** 代替

	//定义xml
	xmlStr = """
	
		
			136124568
			131254225
		
		
			132595965
			133256555
		
		
			133455961
			133289411
		
	
	"""
	def persons = new XmlParser().parseText(xmlStr)
	
	
//depthFirst 深度遍历,可以使用“**” 代替
def phoneList2= persons.depthFirst(){it->
    println it
}
  • 看一眼输出结果:

  • 没错遍历了所有的节点信息,并返回存放在了list中,底层代码是递归遍历,看一下最终调用的源码就明白了

  • 利用这一点我们可以结合集合的知识 ,比如获取 name == Lily 的所有手机号

      def phoneList2 = persons.depthFirst().findAll() { person ->
      	return person.@name == "Lily"
      }.collect() { person ->
          phoneList3 = []
          person.each() { phone ->
              // println phone
              phoneList3.add(phone.text())
          }
          return phoneList3
      }
    
    
      phoneList2.toListString()
    

运行得到结果:

[[132595965, 133256555]]

#####2. 广度遍历,children() 可以使用 * 代替

 	//广度遍历测试
	persons.children().findAll() { person ->
	    println person
	}
  • 运行得到结果:

  • 总结:
  • 广度遍历只遍历当前子节点的内容,不包含当前节点和子节点的信息

深度遍历和广度遍历的区别

名称 简写 是否遍历当前节点 是否遍历下一级子节点 递归遍历子节点的子节点 备注
depthFirst() ** 从当前节点,递归遍历所有节点,包括当前节点
children() * 仅仅遍历当前节点下的一级子节点

2. XML 的生成 - MarkupBuilder手动格式化拼接XML

  • 使用 MarkupBuilder 轻松生成 XML ,传入 StringWriter 可以将 XML 格式信息写入到 StringWriter 中
  • 节点信息写入 xmlBuilder.当前节点名称(key1:value1,key2:value2)
  • 如果包含子节点 xmlBuilder.当前节点名称(key1:value1,key2:value2){
    当前子节点名称(key1:value1,key2:value2)}
  • 如果节点含有值信息 xmlBuilder.当前节点名称(key1:value1,key2:value2){
    当前子节点名称(key1:value1,key2:value2,节点的值)}
	def sw = new StringWriter()
	//使用 MarkupBuilder 可以轻松将xml数据写入到 StringWriter中,最用生成 XML 文件
	def xmlBuilder = new MarkupBuilder(sw)
	//节点信息写入 xmlBuilder.当前节点名称(key1:value1,key2:value2)
	//xmlBuilder.langs(type: 'current', count: '3', mainStream: 'true')
	
	//节点信息写入如果包含子节点 xmlBuilder.当前节点名称(key1:value1,key2:value2){
	// 当前节点名称(key1:value1,key2:value2)}
	xmlBuilder.langs(type: 'current', count: '3', mainStream: 'true') {
	    language(flavor: 'static', version: '1.5', 'java')
	    language(flavor: 'dynamic', version: '1.6', 'Groovy')
	    language(flavor: 'dynamic', version: '1.9', 'javaScript')
	}
	println sw

输出结果:

3. XML 的生成 - 实体类直接转换生成XML

  • 定义实体类:

      class langs {
      
      
          String type = 'current'
          int count = 3
          boolean mainStream = true
      
      
          def language = [new Language(flavor: 'static', version: '1.5', value: 'java'),
                          new Language(flavor: 'dynamic', version: '1.6', value: 'Groovy'),
                          new Language(flavor: 'dynamic', version: '1.9', value: 'javaScript')]
      }
      
      class Language {
          String flavor = 'static'
          String version = '1.5'
          String value = 'java'
      }
    
  • 将实体类解析生成XML

      def sw2 = new StringWriter()
      //使用 MarkupBuilder 可以轻松将xml数据写入到 StringWriter中,最用生成 XML 文件
      def xmlBuilder2 = new MarkupBuilder(sw2)
      
      def langs = new langs()
      xmlBuilder2.langs(type:langs,count:langs.count,mainStream:langs.mainStream){
      
          langs.language.each {lang->
               language(flavor:lang.flavor,version:lang.version,lang.value)
           }
      }
      
      println(sw2)
    
  • 运行结果:

查看 “Android自动化构建系列” 全部文章

你可能感兴趣的:(groovy系列)