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

Grails中如何使用XMLSlurper的setKeepIgnorableWhiteSpace()保留XML格式?

Grails中XmlSlurper保留XML空白格式的正确用法

问题背景

现有一段Grails代码,用于下载XML文件、解析修改后重新写入,代码运行正常但生成的文件丢失所有空白格式:

def xmlFile = simpleSftpService.downloadFile('theFile.xml')
def rootNode = new XmlSlurper().parse(xmlFile)
rootNode.someThing.each(){
    it.thingy='It should be this'
}

def fileName="MyNew.xml"
File writer = File.createTempFile('tempFile', '.xml')
def builder = new StreamingMarkupBuilder()
        writer << builder.bind {
            mkp.yield rootNode
        }
InputStream inputStream = new BufferedInputStream(new FileInputStream(writer))
def storeFile = simpleSftpService.uploadFile(inputStream, fileName)

尝试使用setKeepIgnorableWhiteSpace(true)解决时,以下写法返回null:

def rootNode= new XmlSlurper()
rootNode.setKeepIgnorableWhiteSpace(true)
rootNode.parse(xmlFile)

链式调用写法则抛出空指针异常:

def rootNode=XmlSlurper()setKeepIgnorableWhiteSpace(true).parse(xmlFile)

错误信息:

java.lang.NullPointerException: Cannot invoke method parse() on null object

解决方案

1. 正确设置XmlSlurper的空白保留属性

问题根源:

  • 第一种写法没有将parse()的结果赋值给rootNode,变量实际存储的是XmlSlurper实例,而非解析后的XML节点;
  • 第二种链式调用语法错误,XmlSlurper()不是合法的实例创建方式,需用new XmlSlurper(),且方法调用需正确拼接。

正确的XmlSlurper初始化写法:

def xmlSlurper = new XmlSlurper()
xmlSlurper.setKeepIgnorableWhiteSpace(true)
def rootNode = xmlSlurper.parse(xmlFile)

或者简洁的链式调用写法:

def rootNode = new XmlSlurper().setKeepIgnorableWhiteSpace(true).parse(xmlFile)

2. 配置StreamingMarkupBuilder格式化输出

仅保留解析时的空白还不够,StreamingMarkupBuilder默认会压缩输出,需设置其formatting属性为Formatting.INDENT来保留缩进格式:

def builder = new StreamingMarkupBuilder()
builder.formatting = Formatting.INDENT // 需导入groovy.xml.StreamingMarkupBuilder$Formatting
writer << builder.bind {
    mkp.yield rootNode
}

完整修正后的代码

import groovy.xml.StreamingMarkupBuilder$Formatting

def xmlFile = simpleSftpService.downloadFile('theFile.xml')
// 正确初始化XmlSlurper并保留空白
def rootNode = new XmlSlurper().setKeepIgnorableWhiteSpace(true).parse(xmlFile)

rootNode.someThing.each(){
    it.thingy='It should be this'
}

def fileName="MyNew.xml"
File writer = File.createTempFile('tempFile', '.xml')
def builder = new StreamingMarkupBuilder()
builder.formatting = Formatting.INDENT // 开启缩进格式化
writer << builder.bind {
    mkp.yield rootNode
}

InputStream inputStream = new BufferedInputStream(new FileInputStream(writer))
def storeFile = simpleSftpService.uploadFile(inputStream, fileName)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 17:25:21