How to produce XML DOM indents?

Hi,

I’d like to write a formatted (in particular: indented) Xml file, but the following DOM transformer (identity) doesn’t indent the elements…
(OK, it’s no gaming question but since I use it inside a small game, I am here).

What I would like to have is this (hopefully this board doesn’t eat my indents) :


<Sprite Name="SpritenameA">
  <Anim Fps="60"/>
  <Datei Rgb="Rotier.png" Alpha="Rotier_A.png" />
</Sprite>

However what I actually get is: each line starts at the left, ie no spaces. It reads worse when I have nested elements…

Wham am I doing wrong?

J2SE 1.42, ignoring throws for the following example:


TransformerFactory transfabrik = TransformerFactory.newInstance();
Transformer sTransformer = transfabrik.newTransformer();
sTransformer.setOutputProperty(OutputKeys.INDENT, "yes");

Document sDokument = sBuilder.newDocument();
Element dokuElement = (Element) sDokument.createElement("root");
sDokument.appendChild(dokuElement);

Element spriteElm = sDokument.createElement("Sprite");
spriteElm.setAttribute("Name", "Meinspritename-" + i);

Element animElm = sDokument.createElement("Anim");
animElm.setAttribute("Fps", "60");
spriteElm.appendChild(animElm);
...
dokuElement.appendChild(spriteElm);
dokuElement.appendChild(sDokument.createTextNode("\n\n"));

DOMSource    domquelle = new DOMSource(sDokument);
StreamResult ausgabe   = new StreamResult(System.out); // new File("Datei.xml"));
sTransformer.transform(domquelle, ausgabe);
}

add this:


sTransformer.setOutputProperty("{http://xml.apache.org/xalan}indent-amount","4"); // new property
sTransformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount","4"); // old property

[quote]add this:
(…)
[/quote]
Well, I love such short and efficient problem fixings. :slight_smile:
Thanks a lot, Swpalmer.

With Java 1.5 it doesn’t indent anymore. :frowning:
Couldn’t find anything in the release notes about changes. However a google reports: “Indentation is broken in jdk1.5 beta”

Does this mean it’s also broken in Jdk 1.5 final?
The bugdatabase at
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5064280
suggests some “workaround” and doesn’t consider it as bug.

How to use these workarounds, please?

Knock knock on heaven’s door…
:slight_smile:

(The Korean version of course, as found in the movie “Windstruck”)

[quote]With Java 1.5 it doesn’t indent anymore. :frowning:
Couldn’t find anything in the release notes about changes. However a google reports: “Indentation is broken in jdk1.5 beta”

Does this mean it’s also broken in Jdk 1.5 final?
The bugdatabase at
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5064280
suggests some “workaround” and doesn’t consider it as bug.

How to use these workarounds, please?
[/quote]
Just from reading the bug report it would appear that it was the namespace of the feature which changed — the option was still there. j2se5 final should support the old name as well as the new, otherwise replace http://xml.apache.org/xslt in your code with http://xml.apache.org/xalan

I tried both variants but with no luck. With Java 1.42 the same code outputs indents like expected, but not on java 1.50… :frowning:

This is how I feed the Xml document:


private static Document        sDokument;
private static DocumentBuilder sBuilder;
private static Transformer     sTransformer;

// Konstruktor
DocumentBuilderFactory fabrik = DocumentBuilderFactory.newInstance();
sBuilder = fabrik.newDocumentBuilder();
TransformerFactory transfabrik = TransformerFactory.newInstance();
sTransformer = transfabrik.newTransformer();
sTtransformer.setOutputProperty(OutputKeys.INDENT, "yes");
sTransformer.setOutputProperty("{http://xml.apache.org/xalan} indent-amount", "2");

// Write method is same as in my first article...

In the code above you appear to have a space
“{http://xml.apache.org/xalan} indent-amount”
instead of:
“{http://xml.apache.org/xalan}indent-amount”

I’m not sure if that matters at all.

And you can leave both ‘xalan’ and ‘xslt’ properties in, one may be ignored by some processors, but the one that matters will be picked up.

Unfortunately it didn’t matter (with Java 1.5): no indent.

[quote]And you can leave both ‘xalan’ and ‘xslt’ properties in, one may be ignored by some processors, but the one that matters will be picked up.
[/quote]
Ok, I’ll do that, thanks for the infos.

However with Java 1.5 none of these work so far.

{Edit}
I’m sure I’m not the first one who noticed this. I’ve just posted on a XML dedicated forum, too. It’s a thread inside the Java Technology Forum, subforum Xml.

Well I grepped the source and found that

com/sun/org/apache/xalan/internal/xsltc/compiler/Output.java

seems to have the code on lines 229-248

It is using BOTH of the above properties (‘xalan’ given priority over ‘xslt’)

Oddly I can’t find any reference to READ the “indent_amount” property that that code sets. But it does seem to affect the _indentamount integer variablein the Translet class… which is used in a call to handler.setIndentAmount(int)… Maybe if you set some breakpoints in the Xalan code you can learn more.

What is the output method & media type you are using for the transformer?

[quote]It is using BOTH of the above properties (‘xalan’ given priority over ‘xslt’)
[/quote]
Ok. Now we can say they both should work.

[quote]Oddly I can’t find any reference to READ the “indent_amount” property that that code sets. But it does seem to affect the _indentamount integer variablein the Translet class… which is used in a call to handler.setIndentAmount(int)…
[/quote]
Oh. It’s “indent-amount” actually, not “indent_amount”. But I guess you meant that.

[quote]Maybe if you set some breakpoints in the Xalan code you can learn more.
[/quote]
I’m going to do that. Although I’m an XML greenhorn.

[quote]What is the output method & media type you are using for the transformer?
[/quote]
I don’t set anything extra with the set…Property lines. Would I have to?

PS: Here’s the sumation basic code I use so far


// Set up
TransformerFactory transfabrik  = TransformerFactory.newInstance(); 
Transformer        sTransformer = transfabrik.newTransformer(); 

sTtransformer.setOutputProperty(OutputKeys.INDENT, "yes"); 
sTransformer.setOutputProperty("{http://xml.apache.org/xalan}indent-amount", "2"); 

// Fill Xml elements
DocumentBuilderFactory fabrik = DocumentBuilderFactory.newInstance(); 
DocumentBuilder sBuilder = fabrik.newDocumentBuilder(); 

Document sDokument = sBuilder.newDocument(); 
Element dokuElement = (Element) sDokument.createElement("root"); 
sDokument.appendChild(dokuElement); 

Element someElement = sDokument.createElement("Mainelement"); 
someElement.setAttribute("Name", "Myname"); 

Element anotherElmement = sDokument.createElement("Subelement"); 
anotherElmement.setAttribute("Bla", "60"); 
someElement.appendChild(anotherElmement); 
// etc 
dokuElement.appendChild(someElement); 

// Write file
DOMSource domsource = new DOMSource(sDokument); 
StreamResult output = new StreamResult(System.out); // new File("File.xml")); 
sTransformer.transform(domsource, output); 

[quote]Oh. It’s “indent-amount” actually, not “indent_amount”. But I guess you meant that.
[/quote]
no I meant what I wrote - I’m referring to a java Property in the Xalan source code, not the XSLT transformer property set externally.

Maybe. I have:

Transformer trans = TransformerFactory.newInstance().newTransformer();

trans.setOutputProperty(OutputKeys.METHOD, "xml");

trans.setOutputProperty(OutputKeys.VERSION,"1.0");

trans.setOutputProperty(OutputKeys.MEDIA_TYPE,"text/xml");

trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,"no");

as well as what you have… but I just checked and it also fails to indent on Java 5. Lame.

Could it be THIS bug?

Unfortunately I don’t know.

On the other Java forum somebody responded and refered to http://java.sun.com/j2se/1.5.0/docs/guide/xml/jaxp/JAXP-Compatibility_150.html

… saying this “intend” feature has never been a a documented feature, so maby it could be OK when it broke now.

If it’s never been an official feature: how to intend XML outputs the official way?

Another guy responded in the mentioned Sun forum: http://forum.java.sun.com/thread.jsp?forum=34&thread=562510&message=2783513#2783513

He says this would be the solution for Java 1.5+ [quote]
TransformFactory factory = TransformerFactory.newInstance();
factory.setAttribute(“indent-number”, new Integer(4));
[/quote]
… but it doesn’t work for me, yet.
Does it for you? In case it does: what’s your code looking like, please?

A contributor to the mentioned Java forum thread solved the issue for Java 1.5
Please see article by Philiphooker: http://forum.java.sun.com/thread.jspa?threadID=562510

sTransformer.setOutputProperty("{http://xml.apache.org/xalan}indent-amount",“4”); helped, but it s been applied only for the first line inside the xml doc. How to indent other lines? Thank you, guys!