XMLStreamWriter: 缩进
XMLStreamWriter: 缩进
在Java SE 6中,是否真的没有办法直接使用javax.xml.stream.XMLStreamWriter编写格式化的XML?这真的令人难以置信,因为其他XML API(如JAXB和一些DOM库)都可以做到。即使是.NET的XMLStreamWriter等价物(如果我没记错的话,类名是System.Xml.XmlTextWriter)也能做到这一点。
这意味着我唯一的选择是重新解析XML以生成格式化的输出吗?
例如:
StringWriter sw = new StringWriter(); XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newFactory(); XMLStreamWriter xmlStreamWriter = xmlOutputFactory.createXMLStreamWriter(sw); writeXml(xmlStreamWriter); xmlStreamWriter.flush(); xmlStreamWriter.close(); TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); StringWriter formattedStringWriter = new StringWriter(); transformer.transform(new StreamSource(new StringReader(sw.toString())), new StreamResult(formattedStringWriter)); System.out.println(formattedStringWriter);
这种解决方案的问题在于属性"{http://xml.apache.org/xslt}indent-amount"。我没有找到任何关于它的文档,并且似乎不能保证可移植性。
那么,如果我想使用标准的Java 6类来做到这一点,还有其他选择吗?创建一个用于漂亮打印的JAXB或DOM对象图?
XMLStreamWriter: indentation问题是在使用XMLStreamWriter类时出现的一个问题。该问题的原因是XMLStreamWriter类没有提供直接的方法来实现缩进的功能。
解决该问题的方法是在writeXml方法中添加必要的代码来格式化文档。可以使用一个深度计数器来表示嵌套的层级。然后在调用writeStartElement之前和writeEndElement之后使用深度索引来插入缩进。
具体的代码示例如下:
for(int x=0; x<depth; x++) { xmlStreamWriter.writeCharacters(" "); }
某些情况下在XMLStreamWriter类中找不到writeText方法。确实,应该使用writeCharacters方法来插入文本,而不仅仅在单个元素内部。
相比于使用JAXB来处理XML,使用XMLStreamWriter实现缩进的方法可能会稍微复杂一些。在使用XMLStreamWriter时,需要在每个writeXYZ调用之前调用上述代码,并管理深度。
最后,使用JAXB时,可以通过设置Marshaller的JAXB_FORMATTED_OUTPUT属性为true来轻松地实现缩进的效果。
XMLStreamWriter是Java API for XML Processing (JAXP)中的一种用于写入XML文档的接口。它允许我们以流的方式将XML数据写入输出源。然而,XMLStreamWriter在处理缩进时存在一些限制,导致无法直接设置缩进的数量。
在给定的代码示例中,我们可以看到使用了SAXTransformerFactory和TransformerHandler来创建一个用于输出XML的Transformer。在Transformer中,我们设置了OutputKeys.INDENT属性为"yes",以启用缩进。然后,我们将TransformerHandler的结果设置为一个StreamResult,该结果将写入到XMLStreamWriter中。最后,我们使用XMLOutputFactory创建了一个XMLStreamWriter实例,并将SAXResult传递给它。
然而,在代码的最后一行创建XMLStreamWriter实例时,抛出了一个UnsupportedOperationException异常,错误信息是"Result of type javax.xml.transform.sax.SAXResult is not supported. Supported result types are: DOMResult, StAXResult and StreamResult"。这是因为SAXResult不是XMLStreamWriter支持的结果类型之一。
根据代码注释中提到的,这个问题可能在使用Apache Xerces作为底层实现时可以解决,但不能保证在其他实现中能够工作。
为了解决这个问题,我们可能需要尝试使用其他类型的结果,如DOMResult、StAXResult或StreamResult,以获得XMLStreamWriter的实例。这样,我们就可以使用其他方法来设置缩进的数量,而不是直接设置"{http://xml.apache.org/xslt}indent-amount"属性。
总结起来,XMLStreamWriter在处理缩进时存在一些限制,代码示例中所使用的SAXResult类型不是XMLStreamWriter支持的结果类型之一,导致抛出了UnsupportedOperationException异常。要解决这个问题,可能需要尝试使用其他类型的结果,并使用其他方法来设置缩进的数量。这样,我们可以更好地控制XML文档的输出格式。
问题原因:问题的原因是在使用XMLStreamWriter进行XML格式化时,没有提供缩进功能。
解决方法:使用IndentingXMLStreamWriter类来解决这个问题。这个类可以通过创建一个XMLOutputFactory实例,并将其传递给IndentingXMLStreamWriter的构造函数来使用。代码如下:
XMLOutputFactory xmlof = XMLOutputFactory.newInstance(); XMLStreamWriter writer = new IndentingXMLStreamWriter(xmlof.createXMLStreamWriter(out));
需要注意的是,IndentingXMLStreamWriter是一个com.sun.*类,它并不保证在所有情况下都可用。但是,如果你将IndentingXMLStreamWriter和它的基类DelegatingXMLStreamWriter反编译并保存在自己的项目中,就不再是一个问题了。如果这样做,要记得修复sun代码中的一个bug:在onEmptyElement()方法中,将writeCharacters("\n")改为super.writeCharacters("\n")。
以上就是关于XMLStreamWriter的缩进问题的原因和解决方法。