How to remove insignificant whitespace in XML?

Viewed 56

Consider the following valid Ballerina program that prints twice an XML structure that has been created with XML template:

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

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

The both print statements output the following identical string:

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

First question: how I can create the following output:

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

Without obfuscating the XML template:

// this method doesn't scale for real use cases
xml x = xml`<root ><foo><bar>BAR</bar></foo></root >`;

Second question: in this case xml:strip() looks like no-op. Can it be used to solve the question #1? How to use it correctly? Based on the documentation:

Strips the insignificant parts of the an xml value.

Comment items, processing instruction items are considered insignificant. After removal of comments and processing instructions, the text is grouped into the biggest possible chunks (i.e., only elements cause division into multiple chunks) and a chunk is considered insignificant if the entire chunk is whitespace.

I was expecting to get:

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

But obviously I was wrong.

I'm using:

$ bal --version
Ballerina 2201.2.0 (Swan Lake Update 2)
Language specification 2022R3
Update Tool 1.3.10
1 Answers

xml:strip() won't work here because you are trying to get rid of newline characters that are considered as xml:Text items in your current xml sequence. You could maybe try something like this:

import ballerina/regex;
import ballerina/io;

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

    string text = testXML.toString();
    string[] res = regex:split(text.trim(), "\\s+");
    string tempText = string:'join("", ...res);

    io:StringReader reader = new io:StringReader(tempText);
    xml|error? newXML = reader.readXml();

    io:println(newXML);
}
Related