Groovy自定义 Xml 生成器 BuilderSupport ( 创建 XmlNode 节点 | 管理 XmlNode 节点并将根节点转为 Xml 信息 | 完整代码示例 )
Posted 韩曙亮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Groovy自定义 Xml 生成器 BuilderSupport ( 创建 XmlNode 节点 | 管理 XmlNode 节点并将根节点转为 Xml 信息 | 完整代码示例 )相关的知识,希望对你有一定的参考价值。
文章目录
一、创建 XmlNode 节点
在 class MyBuilderSupport extends BuilderSupport
类中维护一个 Map 集合 , 该 Map 集合用于存储 上一篇博客 【Groovy】自定义 Xml 生成器 BuilderSupport ( 构造 Xml 节点类 | 封装节点名称、节点值、节点属性、子节点 | 将封装的节点数据转为 Xml 字符串 ) 中封装的 XmlNode 节点 ;
该 Map 集合的 Key 是节点名称 , Value 是 XmlNode 节点的值 ;
/**
* Map 集合
* Key 为 节点的 name 名称
* Value 为 节点 XmlNode 对象
*/
def xmlNodes = [:]
createNode 方法 , 是创建节点的方法 , 此处可以创建 XmlNode 节点 , 并放入 Map 集合中 ;
@Override
protected Object createNode(Object name, Map attributes, Object value)
println "创建节点 名称 : $name, 属性 : $attributes, 值 : $value"
xmlNodes.put(name, new XmlNode(name, value, attributes))
return name;
二、管理 XmlNode 节点并将根节点转为 Xml 信息
BuilderSupport#nodeCompleted 方法是节点关闭的回调方法 ;
方法原型如下 :
@Override
protected void nodeCompleted(Object parent, Object node)
super.nodeCompleted(parent, node)
其中 Object node
是被关闭的节点 , Object parent
是被关闭节点的父节点 ;
节点关闭时 , 可以根据 Object node
参数获取该被关闭的节点
def currentXmlNode = xmlNodes[node]
如果该被关闭的节点有父节点 , 即 Object parent
参数不为空 , 则将该节点放入父节点 XmlNode 的 children 子节点集合中 ;
if (parent)
// 该节点有父节点, 将该节点放入父节点的 children 集合中
xmlNodes[parent].children << currentXmlNode
如果该被关闭的节点没有父节点 , 说明该节点就是根节点 , 根节点关闭 意味着 Xml 数据生成完毕 , 此时可以将该根节点输出 ;
// 如果该节点没有父节点, 说明该节点就是根节点, 则开始构建 Xml 文件
currentXmlNode.build(writer)
三、完整代码示例
1、自定义 Xml 生成器 MyBuilderSupport
import groovy.util.BuilderSupport;
import java.util.Map;
public class MyBuilderSupport extends BuilderSupport
/**
* Map 集合
* Key 为 节点的 name 名称
* Value 为 节点 XmlNode 对象
*/
def xmlNodes = [:]
/**
* 写用于出 Xml 数据
*/
Writer writer
MyBuilderSupport(Writer writer)
this.writer = writer
/**
* 设置节点之间的关系
* @param parent Xml 中的父节点
* @param child Xml 中的父节点下的子节点
*/
@Override
protected void setParent(Object parent, Object child)
println "setParent 设置子节点 $child 的父节点是 $parent"
@Override
protected Object createNode(Object name)
/*
所有的 createNode 方法都回调到 3 个参数的 createNode 方法
*/
return createNode(name, null, null);
@Override
protected Object createNode(Object name, Object value)
/*
所有的 createNode 方法都回调到 3 个参数的 createNode 方法
*/
return createNode(name, null, value);
@Override
protected Object createNode(Object name, Map attributes)
/*
所有的 createNode 方法都回调到 3 个参数的 createNode 方法
*/
return createNode(name, attributes, null);
@Override
protected Object createNode(Object name, Map attributes, Object value)
println "创建节点 名称 : $name, 属性 : $attributes, 值 : $value"
xmlNodes.put(name, new XmlNode(name, value, attributes))
return name;
/**
* 闭合节点时, 回调该方法
* @param parent
* @param node
*/
@Override
protected void nodeCompleted(Object parent, Object node)
super.nodeCompleted(parent, node)
println "nodeCompleted 完成了父节点为 parent : $parent 的节点 node : $node 的闭合操作"
def currentXmlNode = xmlNodes[node]
if (parent)
// 该节点有父节点, 将该节点放入父节点的 children 集合中
xmlNodes[parent].children << currentXmlNode
else
// 如果该节点没有父节点, 说明该节点就是根节点, 则开始构建 Xml 文件
currentXmlNode.build(writer)
2、Xml 节点封装了 XmlNode
class XmlNode
/**
* 节点名称
*/
String name
/**
* 节点值
*/
String value
/**
* 节点属性
*/
Map attributes
/**
* 子节点 ArrayList 类型
*/
def children = []
XmlNode(String name, String value, Map attributes)
this.name = name
this.value = value
this.attributes = attributes
/*
<student>
<name code="utf-8">Tom</name>
<age>18</age>
</student>
*/
/**
* 写出该 XmlNode 节点数据
* @param writer
*/
def build(Writer writer)
/*
写出 name 节点名称
注意 : 此处有 2 种情况
① 带属性的节点 <name code="utf-8">Tom</name>
② 不带属性的节点 <age/>
先写出 "<name"
*/
writer.write("<$name")
/*
假如该节点有节点属性信息
循环写出节点属性
*/
if (attributes != null)
attributes.each
writer.write(" $it.key='$it.value'")
/*
可能有如下情况
节点有值, 没有子节点
节点没有值, 没有子节点
节点有值, 有子节点
节点没有值, 有子节点
既没有值有没有子节点
要兼顾处理上述 5 种情况
*/
if (value != null || children != null)
// 处理前 4 种情况
writer.write(">")
if (value != null)
writer.write("$value")
if (children != null)
children.each
it.build(writer)
// 节点收尾
writer.write("</$name>")
else
// 既没有值有没有子节点的情况
// <age/> , 之前写出了 "<age" , 现在写出 "/>"
writer.write("/>")
3、在 Groovy 脚本中生成 Xml 信息
// 用于输出字符串
StringWriter stringWriter = new StringWriter()
// 创建自定义 Xml 构造器
def myBuilderSupport = new MyBuilderSupport(stringWriter)
// 构建 student 根节点
myBuilderSupport.student
// 构建 student 根节点下的 name 节点
// 该节点有 code: "UTF-8" 属性
// 节点元素为 "Tom" 字符串
name("Tom", code: "UTF-8")
age("18")
println ""
println(stringWriter)
执行结果 :
创建节点 名称 : student, 属性 : null, 值 : null
创建节点 名称 : name, 属性 : [code:UTF-8], 值 : Tom
setParent 设置子节点 name 的父节点是 student
nodeCompleted 完成了父节点为 parent : student 的节点 node : name 的闭合操作
创建节点 名称 : age, 属性 : null, 值 : 18
setParent 设置子节点 age 的父节点是 student
nodeCompleted 完成了父节点为 parent : student 的节点 node : age 的闭合操作
nodeCompleted 完成了父节点为 parent : null 的节点 node : student 的闭合操作
<student><name code='UTF-8'>Tom</name><age>18</age></student>
其中
<student><name code='UTF-8'>Tom</name><age>18</age></student>
就是生成的 Xml 数据 ;
以上是关于Groovy自定义 Xml 生成器 BuilderSupport ( 创建 XmlNode 节点 | 管理 XmlNode 节点并将根节点转为 Xml 信息 | 完整代码示例 )的主要内容,如果未能解决你的问题,请参考以下文章
Groovy自定义 Xml 生成器 BuilderSupport ( 构造 Xml 节点类 | 封装节点名称节点值节点属性子节点 | 将封装的节点数据转为 Xml 字符串 )
Android Gradle 插件将自定义 Gradle 插件上传到自建 Maven 仓库 ② ( java 和 groovy 插件自带文档任务 | 自定义文档打包任务 | 生成文档包 )