I'm trying to find a way to format the xml so that each attribute will be in a new line.
我正在尝试找到一种格式化xml的方法,以便每个属性都在一个新行中。
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!
谢谢!
3 个解决方案
#1
2
Just an example of Blaise Doughan answer, with ContentHandler:
用ContentHandler作为Blaise Doughan回答的一个例子:
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();
#2
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.
标准JAXB(JSR-222)API不提供此行为。由于这仅仅是出于审美目的,我建议不必费心去实现它。
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.
如果它是你真正必须拥有的东西,你可以提供ContentHandler的实现。 ContentHandler将接收所有XML事件,然后您可以控制它们如何写入底层OutputStream或Writer。您将需要处理所有格式化逻辑,但是当您编组此ContentHandler时,您将获得所需的确切格式。
#3
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.
有点晚了,但我找到了一个使用名为“DecentXML”的开源xml格式化程序的解决方案。需要一些改变,但总的来说是一个很好的工具。
thanks everyone.
感谢大家。
#1
2
Just an example of Blaise Doughan answer, with ContentHandler:
用ContentHandler作为Blaise Doughan回答的一个例子:
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();
#2
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.
标准JAXB(JSR-222)API不提供此行为。由于这仅仅是出于审美目的,我建议不必费心去实现它。
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.
如果它是你真正必须拥有的东西,你可以提供ContentHandler的实现。 ContentHandler将接收所有XML事件,然后您可以控制它们如何写入底层OutputStream或Writer。您将需要处理所有格式化逻辑,但是当您编组此ContentHandler时,您将获得所需的确切格式。
#3
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.
有点晚了,但我找到了一个使用名为“DecentXML”的开源xml格式化程序的解决方案。需要一些改变,但总的来说是一个很好的工具。
thanks everyone.
感谢大家。