You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 02:00:14