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

groovy.xml.XmlUtil.serialize能否为空节点添加xsi:nil="true"?

Great question! Let's break this down step by step to solve your XML empty node handling issue:

解决XmlUtil.serialize空节点不添加xsi:nil的问题

一、XmlUtil.serialize本身无法直接实现

First off, let's be clear: groovy.xml.XmlUtil.serialize doesn't have built-in configuration to automatically add xsi:nil="true" to empty nodes. It only compresses empty tags like <n:test></n:test> into self-closing ones <n:test/>—no way to tweak this behavior directly. So we need extra processing steps, and the XSLT approach you mentioned is perfect for this.

二、使用XSLT处理XML字符串(匹配你提供的模板)

Java and Groovy fully support XSLT transformations using the JDK's built-in javax.xml.transform APIs. Here's a Groovy code example that uses your exact XSLT template to process the XML string from your StringBuilder:

import javax.xml.transform.TransformerFactory
import javax.xml.transform.stream.StreamSource
import javax.xml.transform.stream.StreamResult
import java.io.StringReader
import java.io.StringWriter

// Your XML payload built from StringBuilder
def xmlPayload = '''<root xmlns:n="http://example.com/ns">
    <n:test></n:test>
    <n:value>Hello</n:value>
    <n:empty/>
</root>'''

// Your provided XSLT template
def xsltTemplate = '''<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*[not(text())]">
        <xsl:copy>
            <xsl:attribute name="xsi:nil">true</xsl:attribute>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>'''

// Execute XSLT transformation
def transformer = TransformerFactory.newInstance().newTransformer(new StreamSource(new StringReader(xsltTemplate)))
def writer = new StringWriter()
transformer.transform(new StreamSource(new StringReader(xmlPayload)), new StreamResult(writer))

def processedXml = writer.toString()
println(processedXml)

This code will convert all empty nodes (both <n:test></n:test> and <n:empty/>) to <n:test xsi:nil="true"/> and <n:empty xsi:nil="true"/>, exactly as you need. If your XML uses namespaces, the XSLT will retain them and automatically add the xsi namespace declaration to the root node if it's missing—fully compliant with XML standards.

三、Alternative: Manual DOM Traversal

If you prefer not to use XSLT, you can use Groovy's DOM manipulation to iterate through nodes and add the attribute manually:

import groovy.xml.XmlParser
import groovy.xml.XmlNodePrinter

def xmlPayload = '''<root xmlns:n="http://example.com/ns">
    <n:test></n:test>
    <n:value>Hello</n:value>
    <n:empty/>
</root>'''

def parser = new XmlParser()
def root = parser.parseText(xmlPayload)

// Traverse all nodes and check for empty content
root.depthFirst().each { node ->
    // Check if node has no text and no child nodes
    if (!node.text() && node.children().isEmpty()) {
        // Ensure xsi namespace exists in root
        if (!root.namespaceMap.containsKey('xsi')) {
            root.namespaceMap['xsi'] = 'http://www.w3.org/2001/XMLSchema-instance'
        }
        node.attributes()['xsi:nil'] = 'true'
    }
}

// Serialize the modified XML
def writer = new StringWriter()
new XmlNodePrinter(new PrintWriter(writer)).print(root)
def processedXml = writer.toString()
println(processedXml)

This method gives you more granular control, which is useful if you have special rules for specific nodes.

Wrap-Up

  • XmlUtil.serialize can't add xsi:nil directly—extra processing is required
  • XSLT is the cleanest, most universal solution, matching the behavior you're familiar with from Microsoft's XSL preprocessor, and it's natively supported in Java/Groovy
  • Manual DOM traversal is a good option for custom node-specific logic

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:37:06