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())
额外注意事项
- MongoDB特殊类型处理:导出的JSON可能包含
ObjectId、ISODate等特殊类型,转XML前要把这些转换成纯字符串(比如ObjectId("xxx")转成"xxx",ISODate("2024-01-01")转成"2024-01-01"),避免XOM解析报错。 - Java 1.7兼容性:Groovy 2.4.6搭配Java 1.7时,要使用兼容的XOM版本(比如XOM 1.3.x系列,不要用过高版本)。
- Excel导入适配:转换后的XML尽量保持根节点下子结构统一,避免Excel导入时出现数据错位。
内容的提问来源于stack exchange,提问作者AKS
相关产品推荐
相关产品推荐

