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

如何在Ballerina中去除XML无关空白及正确使用xml:strip?

Ballerina XML格式化问题

原代码及输出

以下是一段可运行的Ballerina程序,通过XML模板创建XML结构并执行两次打印:

import ballerina/io;
public function main() {
    xml x = xml`<root >
        <foo>
            <bar>BAR</bar>
        </foo>
    </root >`;

    io:println(x);
    io:println(xml:strip(x));
}

两次打印的输出完全一致:

<root>
        <foo>
            <bar>BAR</bar>
        </foo>
    </root>

问题一:生成紧凑格式XML输出

需求是生成无缩进、无换行的紧凑XML输出:

<root><foo><bar>BAR</bar></foo></root>

且不能直接压缩XML模板(如下写法不适用于实际场景):

// 该方式在实际场景中不具备扩展性
xml x = xml`<root ><foo><bar>BAR</bar></foo></root >`;

解决方案

可以通过自定义递归函数遍历XML节点,移除所有仅含空白字符的文本节点,直接拼接元素内容。实现示例如下:

import ballerina/io;
import ballerina/lang.xml;

// 递归处理XML节点,生成紧凑格式字符串
function compactXml(xml xmlVal) returns string {
    string result = "";
    if xmlVal is xml:Element {
        // 拼接元素开始标签
        result += "<" + xmlVal.name.localName;
        // 处理元素属性
        foreach [string key, string val] in xmlVal.attributes {
            result += " " + key + "=\"" + val + "\"";
        }
        result += ">";
        
        // 递归处理子节点
        foreach xml child in xmlVal.children {
            result += compactXml(child);
        }
        
        // 拼接元素结束标签
        result += "</" + xmlVal.name.localName + ">";
    } else if xmlVal is xml:Text {
        // 仅保留非空白文本内容
        string text = xmlVal.value.trim();
        if text != "" {
            result += text;
        }
    }
    // 忽略注释、处理指令等非核心节点
    return result;
}

public function main() {
    xml x = xml`<root >
        <foo>
            <bar>BAR</bar>
        </foo>
    </root >`;

    io:println(compactXml(x));
}

运行后将输出预期的紧凑格式XML。


问题二:xml:strip()的作用与正确使用

为什么xml:strip()看似无作用?

根据官方文档描述:

移除XML值中无意义的部分。
注释项、处理指令项被视为无意义内容。移除注释和处理指令后,文本会被合并为最大可能的块(即只有元素会将文本分割为多个块),如果整个块都是空白字符,则该块被视为无意义内容。

实际运行中xml:strip()未生成紧凑XML的原因是:xml:strip()仅负责移除无意义的空白文本节点,但Ballerina的io:println()方法在打印XML时,会自动为元素添加缩进和换行格式,而非直接输出XML节点的原始结构。也就是说,xml:strip()确实完成了节点清理,但最终的格式化是由输出逻辑导致的。

能否用xml:strip()解决问题一?

xml:strip()本身无法直接生成紧凑输出,因为它仅修改XML节点结构,不控制输出格式。但可以结合xml:strip()和自定义字符串转换实现需求:先用xml:strip()移除空白节点、注释和处理指令,再将处理后的XML转换为无格式字符串。

正确使用xml:strip()的示例

示例代码如下(复用上述compactXml函数):

import ballerina/io;
import ballerina/lang.xml;

public function main() {
    xml x = xml`<root >
        <!-- 这是一段注释 -->
        <foo>
            <bar>BAR</bar>
        </foo>
        <?pi test?>
    </root >`;

    xml strippedXml = xml:strip(x);
    // 此时strippedXml已移除注释、处理指令和空白节点,再转换为紧凑字符串
    io:println(compactXml(strippedXml));
}

// 复用紧凑XML转换函数
function compactXml(xml xmlVal) returns string {
    string result = "";
    if xmlVal is xml:Element {
        result += "<" + xmlVal.name.localName;
        foreach [string key, string val] in xmlVal.attributes {
            result += " " + key + "=\"" + val + "\"";
        }
        result += ">";
        
        foreach xml child in xmlVal.children {
            result += compactXml(child);
        }
        
        result += "</" + xmlVal.name.localName + ">";
    } else if xmlVal is xml:Text {
        string text = xmlVal.value.trim();
        if text != "" {
            result += text;
        }
    }
    return result;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 14:11:29