在unmarshal过程中使用JAXB格式化XML

11

我想在使用JAXB进行反编组时格式化XML文档。

Unmarshaller u = createAndsetUpUnmarshaller(enableValidation, evtHandler, clazz);
return u.unmarshal(new ByteArrayInputStream(stringSource.getBytes()));

在进行编组时,可以通过以下方式格式化代码:

marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

但是对于无法反序列化的过程来说,这是不可能的...... 有什么想法可以在unmarshal过程中(或之后)使用JAXB格式化XML字符串吗?

顺便说一句:我在这里读了一些关于漂亮打印的帖子,但我想用JAXB来做到它!


6
unmarshall操作不会导致一个对象实例吗? - Peter Kofler
1
那么,你想要格式化什么? - Grzegorz Oledzki
但是我想用JAXB来做!- 有什么好的理由“想要”这样做吗?我现在假设你的意思是“在MARSHALLING期间使用JAXB格式化XML”:- XML输出是用来进行转换的,可以说,这是它存在的主要原因;)而且有1000种可能的方法来实现这一点。所以只需按照你想要的方式转换生成的XML即可。 - ivan_ivanovich_ivanoff
为什么这个毫无意义的问题还有一个分数? - dzieciou
此外,将与上述相同的属性设置为unmarshaller将导致异常:javax.xml.bind.PropertyException: name: jaxb.formatted.output value: true(测试时使用了METRO)。 - JBA
4个回答

43

在对XML代码进行反编组时进行格式化在逻辑上是毫无意义的。


1
这听起来很合理,但在受控环境中,有人可能希望将XML代码记录为字符串写入文件。 - Adindu Stevens
它还有助于获取特定行上的错误。如果没有格式化,例如:在第22行,第22列。如果没有格式化,它将只显示在第1行,第220列。 - Salil Kothadia

26

如果您想记录与刚刚取消编组的XML对应的格式化XML,可以使用指定的属性将取消编组的对象重新编组为XML。

/**
 * Marshall input object to a formatted XML String
 */
protected <T> String marshal(T input) throws JAXBException {
    StringWriter writer = new StringWriter();

    JAXBContext jc = JAXBContext.newInstance(input.getClass());
    Marshaller marshaller = jc.createMarshaller();
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
    marshaller.marshal(input, writer);
    return writer.toString();
}

另一方面,如果您只是想重新格式化XML,则应该使用JAXP而不是JAXB。


3
我认为由于JAXB unmarshaller的结果不是XML而是Java对象,因此没有漂亮的打印功能。如果您想更好地漂亮打印结果的解组对象,请重写jaxb生成对象的toString()方法。(这将是一个混乱的解决方案,因为每次生成JAX绑定类时,您都需要自己引入toString()方法。)
嗯...我希望未来的JAXB版本能够解决这个缺点,因为这对于日志记录等非常重要。

0

如果你坚持这样做,一种方法是使用支持“teeing”的XSLT转换器(例如Saxon的转换器),即可以将一个源转换为两个结果对象。我不知道你为什么要调用String#getBytes(); 你应该创建一个StringReader并从中提取。你“tee”的两个目标分别是“identity transform”(如果调用TransformerFactory#newTransformer()则默认)和另一个是JAXBResult。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接