Groovy StreamingMarkupBuilder生成XML时命名空间随机添加问题求助
解决Groovy StreamingMarkupBuilder内部字段自动添加命名空间的问题
问题描述
使用Groovy的StreamingMarkupBuilder构建XML时,根节点声明的ns0命名空间被随机附加到内部fieldConst元素上,期望仅根节点保留该命名空间,所有子元素均不携带命名空间声明。
原代码
import groovy.xml.StreamingMarkupBuilder import groovy.xml.XmlUtil import java.time.LocalDateTime def buildXml() { def mkpBuilder = new StreamingMarkupBuilder() mkpBuilder.encoding = 'utf-8' def clearingXml = mkpBuilder.bind { bld -> mkp.xmlDeclaration() mkp.declareNamespace(ns0: 'urn:document:rfc:functions') 'ns0:rootNode' { fieldDynamic(LocalDateTime.now()) fieldConst(123) fieldConst("abc") } } return XmlUtil.serialize(clearingXml) } println buildXml()
问题输出
<?xml version="1.0" encoding="UTF-8"?><ns0:rootNode xmlns:ns0="urn:document:rfc:functions"> <fieldDynamic>2023-03-07T11:18:01.462405</fieldDynamic> <fieldConst xmlns:ns0="urn:document:rfc:functions">123</fieldConst> <!-- 此处无需命名空间! --> <fieldConst>abc</fieldConst> </ns0:rootNode>
解决方案
问题出在Groovy对不同类型元素内容的隐式处理逻辑上,当直接使用元素名(值)的简写方式时,部分类型的值会触发命名空间的自动继承。修改子元素的构建方式,显式使用闭包包裹值,避免隐式命名空间关联:
修改后的代码
import groovy.xml.StreamingMarkupBuilder import groovy.xml.XmlUtil import java.time.LocalDateTime def buildXml() { def mkpBuilder = new StreamingMarkupBuilder() mkpBuilder.encoding = 'utf-8' def clearingXml = mkpBuilder.bind { bld -> mkp.xmlDeclaration() mkp.declareNamespace(ns0: 'urn:document:rfc:functions') 'ns0:rootNode' { // 显式用闭包包裹值,避免命名空间自动添加 fieldDynamic { mkp.yield(LocalDateTime.now()) } fieldConst { mkp.yield(123) } fieldConst { mkp.yield("abc") } } } return XmlUtil.serialize(clearingXml) } println buildXml()
正确输出
<?xml version="1.0" encoding="UTF-8"?><ns0:rootNode xmlns:ns0="urn:document:rfc:functions"> <fieldDynamic>2023-03-07T11:25:30.123456</fieldDynamic> <fieldConst>123</fieldConst> <fieldConst>abc</fieldConst> </ns0:rootNode>
原理说明
当使用fieldConst(123)这种简写时,Groovy会将数值类型的参数视为元素的属性或命名空间相关参数,导致意外的命名空间声明。通过fieldConst { mkp.yield(123) }显式指定元素内容,强制Groovy将值作为元素文本处理,避免命名空间的自动关联,确保仅根节点保留ns0命名空间声明。
内容的提问来源于stack exchange,提问作者Joseph Cen
相关产品推荐
相关产品推荐

