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

Groovy 2.4.6转JSON到XML遇nu.xom.IllegalNameException问题求助

解决Groovy转JSON到XML时的nu.xom.IllegalNameException问题

我之前处理MongoDB导出的异构JSON转XML时也踩过这个坑,Jenkins任务的JSON结构差异大,很容易触发XML命名规范的问题,下面是亲测有效的解决方案:

核心原因分析

你遇到的nu.xom.IllegalNameException本质是XML的NCName命名规则限制:XML元素名不能以数字、-+数字或其他特殊字符开头。而MongoDB导出的JSON里,大概率存在以数字开头的键(比如某个Jenkins任务的参数名是1_build_number),直接转换就会触发这个异常。


解决方案1:预处理JSON,修正非法键名

转换前先递归遍历JSON的所有键,把不符合XML规范的键名改成合法格式,比如给数字开头的键加key_前缀,或者根据Jenkins任务类型加更有意义的前缀。

给你一段Groovy递归处理的示例代码:

import groovy.json.JsonSlurper
import groovy.json.JsonBuilder

def fixInvalidKeys(obj) {
    if (obj instanceof Map) {
        def fixedMap = [:]
        obj.each { key, value ->
            // 修正以数字开头的键,可扩展处理其他非法字符(比如空格、特殊符号)
            def fixedKey = key ==~ /^\d.*/ ? "key_$key" : key
            // 递归处理嵌套的对象或数组
            fixedMap[fixedKey] = fixInvalidKeys(value)
        }
        return fixedMap
    } else if (obj instanceof List) {
        return obj.collect { fixInvalidKeys(it) }
    } else {
        // 基础类型直接返回
        return obj
    }
}

// 读取MongoDB导出的JSON文件
def jsonText = new File("jenkins_tasks.json").text
def originalJson = new JsonSlurper().parseText(jsonText)
def fixedJson = fixInvalidKeys(originalJson)

// 输出修正后的JSON(可选,用于验证)
new File("fixed_jenkins_tasks.json").write(new JsonBuilder(fixedJson).toPrettyString())

解决方案2:自定义XML转换逻辑,动态修正命名

如果不想提前预处理JSON,也可以在转换XML的过程中直接修正非法键名,用XOM的API手动构建XML节点,完全控制元素命名:

import groovy.json.JsonSlurper
import nu.xom.Document
import nu.xom.Element

def jsonToXmlNode(obj, parentElement) {
    if (obj instanceof Map) {
        obj.each { key, value ->
            // 实时修正非法键名
            def validKey = key ==~ /^\d.*/ ? "key_$key" : key
            def childElement = new Element(validKey)
            parentElement.appendChild(childElement)
            jsonToXmlNode(value, childElement)
        }
    } else if (obj instanceof List) {
        obj.each { item ->
            // 数组元素用统一标签(比如"item"),也可根据内容动态命名
            def itemElement = new Element("item")
            parentElement.appendChild(itemElement)
            jsonToXmlNode(item, itemElement)
        }
    } else {
        // 基础类型直接转为文本内容
        parentElement.appendChild(obj?.toString() ?: "")
    }
}

// 示例用法
def originalJson = new JsonSlurper().parseText(new File("jenkins_tasks.json").text)
def rootElement = new Element("jenkins_tasks")
jsonToXmlNode(originalJson, rootElement)
def xmlDoc = new Document(rootElement)

// 输出XML文件
new File("jenkins_tasks.xml").write(xmlDoc.toXML())

额外注意事项

  1. MongoDB特殊类型处理:导出的JSON可能包含ObjectId、ISODate等特殊类型,转XML前要把这些转换成纯字符串(比如ObjectId("xxx")转成"xxx",ISODate("2024-01-01")转成"2024-01-01"),避免XOM解析报错。
  2. Java 1.7兼容性:Groovy 2.4.6搭配Java 1.7时,要使用兼容的XOM版本(比如XOM 1.3.x系列,不要用过高版本)。
  3. Excel导入适配:转换后的XML尽量保持根节点下子结构统一,避免Excel导入时出现数据错位。

内容的提问来源于stack exchange,提问作者AKS

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:03:28