tags:

views:

58

answers:

4

I am using a Transform object to save my XML file but it seems to drop empty text nodes. Is there any way to create (and keep) a text node with an empty string i.e. "".

Here is how I create the node:

Element type = doc.createElement("TYPE");

type.appendChild(doc.createTextNode(value));

It is just that sometimes value is an empty string "". When I look at the XML with a text editor I see

<TYPE />

instead of

<TYPE></TYPE>

After I read this XML file back in and traverse the nodes the <TYPE> element simply doesn't have any children even though I explicitly created one #text node for it!

EDIT - Happy Thanksgiving (for my fellow Canadians)

Important note, I am not working from a known set of tags, rather the program I am working on uses the presence of a text node to assign a JTextField to the GUI. It is just that sometimes the field is left empty (not null but ""). When I store that field and then read it back the GUI doesn't render the JTextField anymore because there is no text node. So I am looking at ways to create an XML document that creates a text node even if there is nothing in it. If that simply can't be done with XML then I will have to use an attribute to mark tags that are editable (somewhat like Andrey Breslav suggested) and so should have a JTextField assigned.

I will try Mads Hansen's suggestion of a non-breaking space.

+1  A: 

I'd go for a string attribute instead of tag contents. Another option is to use contents but put an attribute in case the contents is empty string.

Andrey Breslav
I tried this and it does work but made the XML file about 20% larger and just didn't look right IMO.
BigMac66
A: 

If you consider the XML specs, an empty string '' is not really defined amongst the set of valid characters. so it is possible that the document builder simply ignores any occurrence of characters which are not valid.

anirvan
+2  A: 

From an XML point of view, there is no difference between <TYPE/> and <TYPE></TYPE>. There are both equivalent and can be used interchangeably. For an XML parser it means, that there is no text. The parser doesn't distinguish between "no text" and a "zero length text".

In contrast Java's null and "" are totally different concepts.

So if you want to map from Java values to XML and vice versa you have to handle that mismatch. And there are several possible alternatives. For example you can abandon null values for your String variables. Then you have to ensure, that all your String variables are initialized with empty strings. Or you can say a TYPE element without a text child (serialized as <TYPE/> or <TYPE></TYPE>) means the empty string in Java and a missing TYPE element stands for null. It's your choice.

vanje
+1  A: 

A text node without text is not a text node.

If you are trying to control how the XML element is serialized, <TYPE/> and <TYPE></TYPE> are equivalent, and it will not matter to an XML processor if either was used. Both are declaring a TYPE element without any text(). Most processors will serialize an empty element as a self-closing element.

If you really want to prevent the element from being serialized as self-closing, you could get cute and add a non-breaking whitespace as the text node value: <TYPE>&#x200B;</TYPE> which will look like: <TYPE></TYPE>.

It isn't technically an "empty" string, but might achieve what you want, and will not pad with space if the text node is selected and used.

Mads Hansen
This does exactly what I want. I had to change my focus listener to replace empty strings with ​ but that was somewhat trivial. The only major drawback is that if someone was manually editing the XML file and forgot to put a non-breaking space in an empty field it messes up my GUI - but I can live with that :)
BigMac66