5

I'm trying to find a way to format the xml so that each attribute will be in a new line.

code :

        OutputFormat of = new OutputFormat();
        of.setIndent(4);
        XMLSerializer serializer = new XMLSerializer(of);
        Writer stringWriter = new StringWriter();
        serializer.setOutputCharStream(stringWriter);

        marshaller.marshal(target, serializer.asContentHandler());
        results = stringWriter.toString();

I'm trying to get this:

<blablabla isGood="false" newInstance="false" id="cse_a"
    deleted="false" name="cse_a"
    xmlns:blabla="http://www.blabla.com">

    <Description><![CDATA[]]></Description>
    <Name><![CDATA[A]]></Name>

</blablabla>

To look like this:

<blablabla isGood="false"
           newInstance="false"
           id="cse_a"
           deleted="false"
           name="cse_a"
           xmlns:blabla="http://www.blabla.com">

    <Description><![CDATA[]]></Description>
    <DisplayName><![CDATA[A]]></DisplayName>

</blablabla>

thanks!

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
David Fischer
  • 1,320
  • 12
  • 14

3 Answers3

2

Just an example of Blaise Doughan answer, with ContentHandler:

import java.io.IOException;
import java.io.Writer;

import org.apache.commons.lang3.StringUtils;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class WriteOutContentHandler extends DefaultHandler
{

    private static final String NEWLINE = System.getProperty("line.separator");
    private static final String INDENT = "  ";

    private Writer _writer;
    private int depth = 0;

    public WriteOutContentHandler(Writer writer)
    {
        _writer = writer;
    }

    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException
    {
        try
        {
            _writer.write(ch, start, length);
        } catch (IOException e)
        {
            throw new SAXException("Error writing out character content", e);
        }
    }

    @Override
    public void ignorableWhitespace(char[] ch, int start, int length)
            throws SAXException
    {
        try
        {
            _writer.write(ch, start, length);
        } catch (IOException e)
        {
            throw new SAXException("Error writing out character content", e);
        }
    }

    @Override
    public void endDocument() throws SAXException
    {
        try
        {
            _writer.flush();
        } catch (IOException e)
        {
            throw new SAXException("Error flushing character output", e);
        }
    }

    @Override
    public String toString()
    {
        return _writer.toString();
    }

    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attrs) throws SAXException
    {
        write(NEWLINE);
        write(StringUtils.repeat(INDENT, depth));
        depth++;

        String eName = localName;

        if ("".equals(eName))
        {
            eName = qName;
        }

        write("<" + eName);

        if (attrs != null)
        {
            for (int i = 0; i < attrs.getLength(); i++)
            {
                String attrName = attrs.getLocalName(i);

                if ("".equals(attrName))
                {
                    attrName = attrs.getQName(i);
                }

                write(NEWLINE);
                write(StringUtils.repeat(INDENT, depth));
                write(attrName);

                write("=\"");
                write(attrs.getValue(i));
                write("\"");
            }
        }

        if (attrs.getLength() > 0)
        {
            write(NEWLINE);
            write(StringUtils.repeat(INDENT, depth-1));
        }

        write(">");
    }

    @Override
    public void endElement(String namespaceURI, String sName, String qName) throws SAXException
    {
        write(NEWLINE);
        depth--;
        write(StringUtils.repeat(INDENT, depth));

        String eName = sName;
        if ("".equals(eName))
        {
            eName = qName;
        }
        write("</" + eName + ">");
    }

    private void write(String s) throws SAXException
    {
        try
        {
            _writer.write(s);
            _writer.flush();
        } catch (IOException e)
        {
            throw new SAXException("I/O error", e);
        }
    }
}

And usage:

    StringWriter writer = new StringWriter();
    JAXBContext jc = JAXBContext.newInstance(MODEL);
    Marshaller marshaller = jc.createMarshaller();
    marshaller.marshal(node, new WriteOutContentHandler(writer));

    return writer.toString();
Popandopolos
  • 628
  • 6
  • 15
1

This behaviour isn't offered by the standard JAXB (JSR-222) APIs. Since this is only for aesthetic purposes I would suggest that it isn't worth the bother to achieve it.

If it's something you really must have, the You could provide an implementation of ContentHandler. A ContentHandler will receive all the XML events and then you can control how they are written to the underlying OutputStream or Writer. You will need to handle all the formatting logic, but when you marshal to this ContentHandler you will get the exact format you are looking for.

bdoughan
  • 147,609
  • 23
  • 300
  • 400
0

A bit late, but I've found a solution using an open source xml formatter called "DecentXML". Needed a few changes, but all in all a great tool.

thanks everyone.

David Fischer
  • 1,320
  • 12
  • 14