Java XMLStreamWriter:缩进
是否真的没有办法使用javax.XML.stream.XMLStreamWriter(JavaSE6)直接编写格式化的XML???这真是难以置信,因为其他XML API(如JAXB和一些DOM库)能够做到这一点。即使是与.NET XMLStreamWriter等效的程序也可以实现这个AFAIK(如果我没记错的话,这个类是System.Xml.XmlTextWriter) 这意味着我唯一的选择是重新分析XML以生成格式化输出 例如: 此解决方案的问题在于“属性”{http://xml.apache.org/xslt}缩进金额”。我没有找到任何关于它的文档,而且似乎也不能保证它是可移植的Java XMLStreamWriter:缩进,java,xml,Java,Xml,是否真的没有办法使用javax.XML.stream.XMLStreamWriter(JavaSE6)直接编写格式化的XML???这真是难以置信,因为其他XML API(如JAXB和一些DOM库)能够做到这一点。即使是与.NET XMLStreamWriter等效的程序也可以实现这个AFAIK(如果我没记错的话,这个类是System.Xml.XmlTextWriter) 这意味着我唯一的选择是重新分析XML以生成格式化输出 例如: 此解决方案的问题在于“属性”{http://xml.apache
那么,如果我想用标准Java6类实现这一点,我还有什么其他选择呢?创建一个JAXB或DOM对象图只是为了进行漂亮的打印???您可以添加必要的代码以在writeXml方法中格式化文档。只需维护一个深度计数器(以指示嵌套的级别)。然后在WriteStarteElement之前和WriteDelete之后,使用深度索引插入缩进
for(int x=0; x<depth; x++) {
xmlStreamWriter.writeCharacters(" ");
}
for(int x=0;x标准java.xml接口对序列化几乎没有控制是正确的,即使底层实现(Apache Xerces)是的。我必须解决这个问题,我想到的最好办法是包含Xerces的一个副本,并使用org.apache.xml.serialize
类。几个月前就已经回答了这个问题,就是使用IndentingXMLStreamWriter类:
XMLOutputFactory xmlof = XMLOutputFactory.newInstance();
XMLStreamWriter writer = new IndentingXMLStreamWriter(xmlof.createXMLStreamWriter(out));
就代码而言,这是一个简洁的解决方案,但要小心:这是一个com.sun.*类,不能保证它的通用性…对于Spring Batch,这需要一个子类,因为
公共类缩进TaxeventionItemWriter扩展了StatxeventionItemWriter{
@塞特
@吸气剂
私有布尔缩进=真;
@凌驾
受保护的XMLEventWriter createXmlEventWriter(XMLOutputFactory outputFactory,Writer-Writer)抛出XMLStreamException{
if(isIndenting()){
返回新的缩进XMLEventWriter(super.createXmlEventWriter(outputFactory,writer));
}
否则{
返回super.createXmlEventWriter(outputFactory,writer);
}
}
}
但这需要额外的依赖关系,因为Spring批处理不包括缩进StAX输出的代码:
<dependency>
<groupId>net.java.dev.stax-utils</groupId>
<artifactId>stax-utils</artifactId>
<version>20070216</version>
</dependency>
net.java.dev.stax-utils
斯塔克斯乌提尔斯酒店
20070216
作为记录,Saxon允许您通过s9api接口获取序列化XMLStreamWriter:
Processor p = new Processor();
Serializer s = p.newSerializer();
s.setOutputProperty(Property.INDENT, "yes");
XMLStreamWriter w = s.getXMLStreamWriter();
序列化程序公开所有XSLT定义的输出属性(包括“缩进”)以及一些特定于Saxon的属性。考虑到,我没有答案{http://xml.apache.org/xslt}“缩进金额”
property。但是您可以在某种程度上方便地使用transformers,而无需重新分析所有输出。您可以使用下面的代码创建漂亮的打印XMLStreamWriter
public static void main(String[] args) {
XMLStreamWriter xmlStreamWriter = createXMLStreamWriter(new OutputStreamWriter(System.out));
writeXml(xmlStreamWriter);
}
private static XMLStreamWriter createXMLStreamWriter(Writer textWriter) throws XMLStreamException {
SAXTransformerFactory xmlTransformerFactory = (SAXTransformerFactory)SAXTransformerFactory.newInstance();
TransformerHandler transformingSAXHandler;
try {
transformingSAXHandler = xmlTransformerFactory.newTransformerHandler();
} catch (TransformerConfigurationException e) {
throw new XMLStreamException(e);
}
Transformer xmlTransformer = transformingSAXHandler.getTransformer();
xmlTransformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformingSAXHandler.setResult(new StreamResult(textWriter));
XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newInstance();
return xmlOutputFactory.createXMLStreamWriter(new SAXResult(transformingSAXHandler));
}
我找不到这样的writeText方法?!你是对的,它应该是writeCharacters。此方法可用于在文档中的任何位置插入文本,而不仅仅是在单个元素中。我想我必须在任何writeXYZ调用之前调用此方法(例如,使用包装器)并且,正如您所说,管理深度。可能是可行的,但不像JAXB:marshaller.setProperty(marshaller.JAXB_格式化的_输出,true)那样简单;是的,我读过关于此类解决方案的文章,但自从Xerces 2.9.0以来,这个软件包就被弃用了:有趣的部分是stax utils库,它提供了IndentingXMLEventWriter,似乎独立于Spring Batch。感谢您的提示!正如您所说,不幸的是,这不是一个已发布的API。IndentingXMLStreamWriter
class及其基类DelegatingXMLStreamWriter
可以用反编译器打开(IntelliJ IDEA现在有一个内置的)并以源代码形式保存为我们自己项目的一部分。因此,它们的“未发布”并不是一个真正的问题。如果你这样做,一定要修复sun代码中的一个错误:Onemptylement()
method,调用writeCharacters(“\n”);
应该是super.writeCharacters(“\n”);
相反。这里有一个稍微完整的版本:最后一行导致:java.lang.UnsupportedOperationException:类型为javax.xml.transform.sax的结果。SAXResult@184f6be2不支持。支持的结果类型有:DOMResult、StAXResult和StreamResult
。我们使用Java版本1.8u74,你呢?我认为它应该在ng实现是Apache Xerces,但不能保证与其他实现一起工作……请原谅,什么是writeXml()
?最好提供您代码的所有必要部分,以便您可以在遇到与您相同的问题时尝试(我的情况),但我不知道它是什么(背后是什么代码)不幸的是,我无法尝试。
Processor p = new Processor();
Serializer s = p.newSerializer();
s.setOutputProperty(Property.INDENT, "yes");
XMLStreamWriter w = s.getXMLStreamWriter();
public static void main(String[] args) {
XMLStreamWriter xmlStreamWriter = createXMLStreamWriter(new OutputStreamWriter(System.out));
writeXml(xmlStreamWriter);
}
private static XMLStreamWriter createXMLStreamWriter(Writer textWriter) throws XMLStreamException {
SAXTransformerFactory xmlTransformerFactory = (SAXTransformerFactory)SAXTransformerFactory.newInstance();
TransformerHandler transformingSAXHandler;
try {
transformingSAXHandler = xmlTransformerFactory.newTransformerHandler();
} catch (TransformerConfigurationException e) {
throw new XMLStreamException(e);
}
Transformer xmlTransformer = transformingSAXHandler.getTransformer();
xmlTransformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformingSAXHandler.setResult(new StreamResult(textWriter));
XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newInstance();
return xmlOutputFactory.createXMLStreamWriter(new SAXResult(transformingSAXHandler));
}