How to avoid extra blank lines in XML generation with Java?

white spaces can be preserved by xml true or false
remove empty lines
java remove empty lines from string
space in xml tag
remove empty lines javascript
java remove last empty line
remove empty lines python
remove empty lines php

Currently I'm trying to develop some code with Java 9 and javax.xml libraries (both mandatory for my task) that edits an XML file and I'm having some weird issues adding child nodes.

This is the XML file:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<users>
</users>

and I want to edit it build something like this:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<users>
    <user>
        <name>A name</name>
        <last-name>Last Name</last-name>
        <username>username</username>
    </user>
</users>

Now, the first run of the code adds a single blank line before the <user> node. When it runs for a second time fills with more blank lines:

<users>


    <user>

        <name>name</name>

        <last-name>lastname</last-name>

        <username>username</username>

    </user>

    <user>
        <name>name</name>
        <last-name>lastname</last-name>
        <username>username</username>
    </user>
</users>

This is the XML generated after running the program 2 times. As you can see, it adds blank lines before the <user> nodes and between the other nodes, exactly n-1 blank lines between nodes being n the times the code was executed.

Wondering what is the content of those nodes before updating the file I wrote the next code:

int i=0;
while (root.getChildNodes().item(i)!=null){
  Node aux = root.getChildNodes().item(i);
  System.out.println("Node text content: ".concat(aux.getTextContent()));
  i++;
}

1st execution:

Node text content: 

Node text content: namelastnameusername

2nd execution:

Node text content: 


Node text content: 
        name
        lastname
        username

Node text content: 

Node text content: namelastnameusername

3rd execution

Node text content: 



Node text content: 

        name

        lastname

        username


Node text content: 


Node text content: 
        name
        lastname
        username

Node text content: 

Node text content: namelastnameusername

Finally, this is the Java code:

private static void saveUser(String firstName, String lastName, String username){
  DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    try {
      DocumentBuilder builder = factory.newDocumentBuilder();
      Document doc = builder.parse(new File(databaseFile));
      Element root = doc.getDocumentElement();
      root.normalize();

      // build user node
      Element userNode = doc.createElement("user");
      Element nameNode =  doc.createElement("name");
      Element lastNameNode = doc.createElement("last-name");
      Element usernameNode = doc.createElement("username");

      //build structure
      nameNode.appendChild(doc.createTextNode(firstName));
      lastNameNode.appendChild(doc.createTextNode(lastName));
      usernameNode.appendChild(doc.createTextNode(username));

      userNode.appendChild(nameNode);
      userNode.appendChild(lastNameNode);
      userNode.appendChild(usernameNode);
      root.appendChild(userNode);

      //write the updated document to file or console
      TransformerFactory transformerFactory = TransformerFactory.newInstance();
      Transformer transformer = transformerFactory.newTransformer();
      DOMSource source = new DOMSource(doc);
      StreamResult result = new StreamResult(new File(databaseFile));
      transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
      transformer.setOutputProperty(OutputKeys.INDENT, "yes");
      transformer.transform(source, result);
    }catch (SAXException | ParserConfigurationException | IOException | TransformerException e1) {
      e1.printStackTrace();
    }
}

The only solution I could find is to delete blank lines after XML generation, but I think it's not a proper solution and I would like to find some alternatives first.

Any suggestions on how to tackle this problem?

I suspect it's the Transformer that's adding the blank lines.

Instead of using the default transformer (transformerFactory.newTransformer()), try passing in an XSLT that has xsl:strip-space set (transformerFactory.newTransformer(new StreamSource(new File(PATH_TO_XSLT_FILE)));)...

XSLT File

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

How to remove extra empty lines from XML file?, Use Java code to do this: use XPath to find all whitespace-only TEXT nodes, This will remove all the generated empty spaces in the XML file. place the text you want to keep in a variable(ie text ); set the node text to "" using node. very well how the extra empty lines in the xml output are actually extra nodes of type text. Re: how to remove empty lines from xml files after removing nodes from document user12185243 Apr 7, 2013 4:14 AM ( in response to EJP )

In Short: Actually, in Java 9, you may only take the way of deleting the blank line after xml generated or after xml parsed from file, like :

private void clearBlankLine(Element element) {
    NodeList childNodes = element.getChildNodes();
    for (int index = 0; index < childNodes.getLength(); index++) {
        Node item = childNodes.item(index);
        if (item.getNodeType() != 1 && System.lineSeparator()
            .equals(item.getNodeValue())) {
            element.removeChild(item);
        } else {
            if (item instanceof Element) {
                clearBlankLine((Element) item);
            }
        }
    }
}

Then invoke this with root element.

Details:

In the flow of xml generation, there are three lifecycle for each element parse: startElement,parse,endElement. While the indent feature is implemented in the startElement scope. Also the indent will add a blank line in document.

The invoke stack is different in java 8 between java 9:

In Java 8: ToStream#startElement-> ToStream#indent(IfNecessary)

In Java 9: ToStream#startElement->ToStream#flushCharactersBuffer(IfNecessary)->ToStream#indent(IfNecessary)

While the flushCharactersBuffer also do indent when we open the indent feature like: transformer.setOutputProperty(OutputKeys.INDENT, "yes"); Also the condition to invoke method: flushCharactersBuffer and method: indent almost same.

That means in Java 9, this would add two new line for each need indented element, result to blank lines appeared.

Remove blank lines in format action, Engage Youre Whole Organization In Content Creation The Format and Indent action removes the blank lines if they are not included in Are the blank lines included in an element listed in the Preserve Space Elements list in Preferences -​> Editor -> Format -> XML? Too many options to keep up with! Hi, I wanted to delete a line from xml file which i did it. But after deletion of that line there is a blank space. Again if i am adding another line by using java that blank line remains as usual.

your solution and below suggestion are both works fine for me, please try with this test case,

public static void main(String[] args) {

    saveUser("test one", "test two", "test three");

}

private static void saveUser(String firstName, String lastName, String username){
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    try {
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(new File("second.xml"));
        Element root = doc.getDocumentElement();
        root.normalize();

        // build user node
        Element userNode = doc.createElement("user");
        Element nameNode =  doc.createElement("name");
        Element lastNameNode = doc.createElement("last-name");
        Element usernameNode = doc.createElement("username");

        userNode.appendChild(nameNode).setTextContent(firstName); //set the text content
        userNode.appendChild(lastNameNode).setTextContent(lastName);
        userNode.appendChild(usernameNode).setTextContent(username);
        root.appendChild(userNode);

        //write the updated document to file or console
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        DOMSource source = new DOMSource(doc);
        StreamResult result = new StreamResult(new File("second.xml"));
        transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.transform(source, result);

     }catch (Exception e) {
        e.printStackTrace();
     }
}

second.xml (before execution)

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<users>
</users>

second.xml (first execution)

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<users>
<user>
<name>test one</name>
<last-name>test two</last-name>
<username>test three</username>
</user>
</users>

second.xml (second execution)

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<users>
<user>
<name>test one</name>
<last-name>test two</last-name>
<username>test three</username>
</user>
<user>
<name>test one</name>
<last-name>test two</last-name>
<username>test three</username>
</user>
</users>

second.xml (third execution)

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<users>
<user>
<name>test one</name>
<last-name>test two</last-name>
<username>test three</username>
</user>
<user>
<name>test one</name>
<last-name>test two</last-name>
<username>test three</username>
</user>
<user>
<name>test one</name>
<last-name>test two</last-name>
<username>test three</username>
</user>
</users>

importing classes,

import java.io.File;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.parsers.DocumentBuilder; // missing import class

import org.w3c.dom.Document;
import org.w3c.dom.Element;

Best Remove Empty Lines Online tool, Word to HTML Converter · JSON to JAVA Converter · XML to JAVA Converter · Online Tableizer · HTML to CSV Converter · HTML to TSV Converter · HTML to  What can you do with Remove Empty Lines? This will remove empty lines from provided text or input string. How to Remove Empty Lines? Example. Here is a Text: Hello World. Text version: Output : Hello World

Sams Teach Yourself Beginning Programming in 24 Hours, Your computer or web browser must emulate a virtual machine to run a Java applet or application. XML Extensible Markup Language. NET-based web pages and applications. whitespace Extra blank lines and spaces inside A step​-by-step routine that walks you through a process such as the creation of a program. DOM Serialization. When serializing an XML document, the output indentation adds insignificant whitespace. By default, the Oracle XDK DOM parser prints the XML DOM document with indentation. To avoid indentation, using XDK 9i, you can sub-class the oracle.xml.parser.v2.XMLPrintDriver class as follows (see Example 4):

Beginning Programming in 24 Hours, Sams Teach Yourself: Begi Prog , Your computer or web browser must emulate a virtual machine to run a Java applet or application. XML Extensible Markup Language. NET-based web pages and applications. whitespace Extra blank lines and spaces inside A step​-by-step routine that walks you through a process such as the creation of a program. The Jackson XML module adds some additional support for XML specific features. These annotations allow us to control the XML namespace and local name for elements, including the root element, whether a field is rendered in an element or as plain text, whether the content of an element is rendered in a CData wrapper, and whether a collection

What You Need to Know About Whitespace in XML, Learn about the concept of XML whitespace, and gets tips for avoiding Similarly, sometimes the XSLT transformation doesn't generate the results you expected. any leading and trailing spaces from the string passed to it as an argument. MyXMLPrintDriver extends XMLPrintDriver { public MyXMLPrintDriver(java.io. Sergiy is right: XML is about data, not about presentation. The presentation (including line breaks) is taken care of by the stylesheet. There is a lot you can do in the stylesheet for presenting the data as you would like to see themin the browser (BTW, the stylesheet is the submittors responsibility, the one from CDISC is ONLY an examle).

Comments
  • Did you try my suggestion of specifying the XSLT to use when creating the transformer?
  • Sorry for the delay and thank you for reminding me. Your suggestion did the trick :)
  • It works like a charm, thank you. Although, it will put the first <users> tag at the same level as <?xml version="1.0" encoding="UTF-8"?>: <?xml version="1.0" encoding="UTF-8"?><users>. To me it's fine, but maybe the XSLT can be modified in order to prevent that as well?
  • Thanks for the explanation. It seems I cannot do it without actively deleting those blank lines :(
  • I have the exact same result as before
  • @PabloRiutort it is a work for me, please refer the above edited answer
  • I have executed your code and I got the same result: more and more blank lines piled up. Can I see your imports?
  • @PabloRiutort please refer the above edited answer
  • Same result with your imports. Added missing javax.xml.parsers.DocumentBuilder. What version of Java do you use?