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

如何使用Groovy MarkupBuilder生成不带引号的数值属性?

如何用Groovy的MarkupBuilder生成不带引号的属性

默认情况下Groovy的MarkupBuilder会给所有XML属性值添加引号,无论类型。要实现部分属性不带引号,需要借助更灵活的处理方式,以下是可行方案:

方案1:使用StreamingMarkupBuilder(推荐)

StreamingMarkupBuilder允许直接嵌入原始XML片段,能精准控制属性的引号状态:

def writer = new StringWriter()
def xml = new groovy.xml.StreamingMarkupBuilder().bind {
    consolidate(
        // 直接编写不带引号的属性
        'amount=220.36',
        date: "2023-01-06",
        invoiceId: "123456XXX",
        currency: 'EUR'
    )
}
writer << xml
println writer.toString()

执行后生成的结果符合预期:

<consolidate amount=220.36 date="2023-01-06" invoiceId="123456XXX" currency="EUR"/>

方案2:自定义MarkupBuilder的属性渲染逻辑

如果坚持使用MarkupBuilder,可以通过继承并重写属性处理方法实现,但相对繁琐:

class CustomMarkupBuilder extends groovy.xml.MarkupBuilder {
    CustomMarkupBuilder(Writer writer) {
        super(writer)
    }

    @Override
    protected void printAttributes(Map attrs) {
        attrs.each { key, value ->
            writer.write(" $key")
            if (value != null) {
                // 指定amount属性不加引号,其他属性保留默认引号逻辑
                if (key == 'amount') {
                    writer.write("=$value")
                } else {
                    writer.write("=\"${encodeAttribute(value.toString())}\"")
                }
            }
        }
    }
}

// 使用自定义Builder生成XML
def writer = new StringWriter()
def xml = new CustomMarkupBuilder(writer)
xml.setDoubleQuotes(true)

def invoiceId = "123456XXX"
def date = "2023-01-06"
def amount = 220.36

xml.consolidate(
    amount: amount.toDouble(),
    date: date,
    invoiceId: invoiceId,
    currency: 'EUR'
)

println writer.toString()

⚠️ 注意:XML规范中属性值必须加引号,虽然多数解析器能兼容不带引号的数值,但这种写法不符合标准语法,可能在严格解析场景下出现问题,建议谨慎使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 14:40:18