Format XML, one attribute per line, with JDom
I use JDom for XML parsing / formatting. I would like long lines of attributes to be split into several lines.
Like :
<node att1="Foo" att2="Bar" att3="Foo" />
Into :
<node
att1="Foo"
att2="Bar"
att3="Foo" />
A开发者_如何转开发ccording to the JDom FAQ, JDom can be transformed into standard DOM and SAX events. So any renderer that supports SAX or DOM and is capable of such pretty rendering would be great.
Thanks in advance.
Ok, I didn't find any class that did that. So I implemented one myself as a sub class of org.jdom.output.XMLOutputter
import java.io.IOException;
import java.io.Writer;
import java.util.*;
import org.jdom.Attribute;
import org.jdom.Element;
import org.jdom.output.XMLOutputter;
/** This outputter prints each attributes in a new line */
public class OneAttributePerLineOutputter extends XMLOutputter {
// ----------------------------------------------------
// Attribute
// ----------------------------------------------------
/** Limit wrapping attribute for one namespace */
String namespace = null;
/** Number of inline attributes before wrapping */
private int nbInlineAttribs;
// ----------------------------------------------------
// Constructor
// ----------------------------------------------------
/**
* @param namespace Limit wrapping attributes to one namespace. If null, all attributes are concerned
* @param nbInlineAttribs Allow a given number of inline elements before wrapping to several lines
*/
public OneAttributePerLineOutputter(
String namespace,
int nbInlineAttribs)
{
this.namespace = namespace;
this.nbInlineAttribs = nbInlineAttribs;
}
// ----------------------------------------------------
// Helpers
// ----------------------------------------------------
static private int elementDepth(Element element) {
int result = 0;
while(element != null) {
result++;
element = element.getParentElement();
}
return result;
}
// ----------------------------------------------------
// Overridden methods
// ----------------------------------------------------
@Override protected void printAttributes(
Writer writer,
List attribs,
Element parent,
NamespaceStack ns) throws IOException
{
// Loop on attributes
for (Object attribObj : attribs) {
Attribute attrib = (Attribute) attribObj;
// Check namespace
if ((this.namespace == null) ||
(this.namespace.equals(attrib.getNamespaceURI())))
{
// Reached max number of inline attribs ?
if (attribs.size() > this.nbInlineAttribs) {
// New line
writer.append("\n");
// Indent
for (int i=0; i < elementDepth(parent); i++) {
writer.append(this.getFormat().getIndent());
}
}
}
// Output single atribute
List list = new ArrayList<Object>();
list.add(attrib);
super.printAttributes(writer, list, parent, ns);
}
}
}
This serializer will follow the indent policy of the given Format.
It allows to apply attribute wrapping to a single namespace only (I needed that feature) and you can specify the maximum number of inline attributes you allow before it wraps them.
I hope this can be useful to someone.
精彩评论