Groovy XML处理问题:拆分CompoundEmployee节点时格式异常
修正Groovy StreamingMarkupBuilder生成XML的节点渲染问题
问题根源
直接将Groovy的Node对象传入StreamingMarkupBuilder时,会默认调用其toString()方法,导致输出Node@xxxx这类字符串,而非预期的XML嵌套结构。需要递归遍历节点的属性、子节点,手动构建XML结构。
解决方案
1. 编写递归渲染Node的辅助方法
这个方法会遍历节点的所有属性和子元素,将它们转换成StreamingMarkupBuilder可识别的语法:
def renderNode(Node node) { // 处理节点属性 def attrs = node.attributes() // 处理子节点和文本内容 return { if (attrs) { attrs.each { key, value -> "${key}"(value) } } node.children().each { child -> if (child instanceof Node) { "${child.name()}"(renderNode(child)) } else if (child instanceof String || child instanceof GString) { // 处理文本节点 mkp.yield(child) } } } }
2. 生成对应数量的CompoundEmployee节点
以下是完整的示例代码,包含XML解析、节点复用和目标XML生成:
import groovy.xml.StreamingMarkupBuilder import groovy.xml.XmlParser // 模拟原始输入XML def originalXml = ''' <root> <personal_information> <first_name>John</first_name> <last_name>Doe</last_name> </personal_information> <email_information> <email>john.doe@example.com</email> </email_information> <employment_information> <job_title>Developer</job_title> <department>Engineering</department> </employment_information> <employment_information> <job_title>Senior Developer</job_title> <department>Engineering</department> </employment_information> </root> ''' // 解析原始XML def parser = new XmlParser() def rootNode = parser.parseText(originalXml) // 获取需要复用的节点 def personalInfo = rootNode.personal_information[0] def emailInfo = rootNode.email_information[0] def employmentList = rootNode.employment_information // 使用StreamingMarkupBuilder生成目标XML def builder = new StreamingMarkupBuilder() builder.encoding = 'UTF-8' def resultXml = builder.bind { mkp.xmlDeclaration() CompoundEmployees { // 每个employment_information对应一个CompoundEmployee employmentList.each { emp -> CompoundEmployee { // 渲染复用的节点 "${personalInfo.name()}"(renderNode(personalInfo)) "${emailInfo.name()}"(renderNode(emailInfo)) // 渲染当前employment节点 "${emp.name()}"(renderNode(emp)) } } } } // 输出结果 println resultXml
代码说明
renderNode方法递归处理每个Node的属性和子元素,确保所有嵌套结构都被正确渲染成XML标签,而非Node对象的字符串表示。- 遍历所有
employment_information节点,每个节点对应生成一个新的CompoundEmployee,同时复用原始的personal_information和email_information内容。 - 使用
mkp.yield处理文本节点,避免纯文本内容被错误解析成标签。
内容的提问来源于stack exchange,提问作者SURAJIT NEOGI
相关产品推荐
相关产品推荐

