Java 中的 StAX XML 格式

Posted

技术标签:

【中文标题】Java 中的 StAX XML 格式【英文标题】:StAX XML formatting in Java 【发布时间】:2010-09-22 08:44:30 【问题描述】:

是否可以使用 StAX(特别是 woodstox)使用换行符和制表符格式化输出 xml,即格式:

一些数据 元素2> 元素1>

代替:

someData

如果这在woodstox 中是不可能的,是否还有其他轻量级库可以做到这一点?

【问题讨论】:

【参考方案1】:

有com.sun.xml.txw2.output.IndentingXMLStreamWriter

XMLOutputFactory xmlof = XMLOutputFactory.newInstance();
XMLStreamWriter writer = new IndentingXMLStreamWriter(xmlof.createXMLStreamWriter(out));

【讨论】:

据我所知,命名空间要么有错误,要么已移至 com.sun.xml.internal.txw2.output。 @epeleg 不,“内部”版本与 JRE 捆绑在一起。您可以通过显式添加 JAXB-RI 作为依赖项来获取非内部版本。【参考方案2】:

通过 JDK:transformer.setOutputProperty(OutputKeys.INDENT, "yes");

【讨论】:

该方法的链接在https后面漏掉了一个冒号 @Josh 链接已损坏。这种方法是在 SO 上提出的:Formatting XML file using StAX 我在回答中添加了更多上下文:***.com/a/38371920/480894 那不是答案。什么变压器?怎么用? @pavel_k docs.oracle.com/javase/7/docs/api/index.html?javax/xml/… 我假设如果您使用 Java 编程,您知道如何参考 Java 文档并尝试自己首先实现解决方案【参考方案3】:

使用 JDK Transformer:

public String transform(String xml) throws XMLStreamException, TransformerException

    Transformer t = TransformerFactory.newInstance().newTransformer();
    t.setOutputProperty(OutputKeys.INDENT, "yes");
    t.setOutputProperty("http://xml.apache.org/xsltindent-amount", "2");
    Writer out = new StringWriter();
    t.transform(new StreamSource(new StringReader(xml)), new StreamResult(out));
    return out.toString();

【讨论】:

【参考方案4】:

如果您使用的是 StAX 游标 API,您可以通过将 XMLStreamWriter 包装在 indenting proxy 中来缩进输出。我在自己的项目中尝试过,效果很好。

【讨论】:

【参考方案5】:

与其依赖可能会消失的 com.sun...class(或重命名为 com.oracle...class),我建议从 java.net 下载 StAX utility classes。这个包包含一个很好用的 IndentingXMLStreamWriter 类。 (源代码和javadoc包含在下载中。)

【讨论】:

【参考方案6】:

StaxMate怎么样:

http://www.cowtowncoder.com/blog/archives/2006/09/entry_21.html

适用于 Woodstox、快速、低内存使用(未构建内存树)以及如下缩进:


SMOutputFactory sf = new SMOutputFactory(XMLOutputFactory.newInstance());
SMOutputDocument doc = sf.createOutputDocument(new FileOutputStream("output.xml"));
doc.setIndentation("\n ", 1, 2); // for unix linefeed, 2 spaces per level    
// write doc like:    
SMOutputElement root = doc.addElement("element1");    
root.addElement("element2").addCharacters("someData");    
doc.closeRoot(); // important, flushes, closes output

【讨论】:

【参考方案7】:

如果您使用的是迭代方法 (XMLEventReader),您不能在写入 XML 文件时将换行符 '\n' 附加到相关的 XMLEvents 中吗?

【讨论】:

【参考方案8】:

不确定 stax,但最近有一个关于漂亮打印 xml here 的讨论

pretty print xml from java

这是我尝试的解决方案

How to pretty print XML from Java?

使用 org.dom4j.io.OutputFormat.createPrettyPrint() 方法

【讨论】:

【参考方案9】:

如果您使用的是 XMLEventWriter,那么更简单的方法是:

XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
        XMLEventWriter writer = outputFactory.createXMLEventWriter(w);
        XMLEventFactory eventFactory = XMLEventFactory.newInstance();
        Characters newLine = eventFactory.createCharacters("\n"); 
        writer.add(startRoot);
        writer.add(newLine);

【讨论】:

【参考方案10】:

对于 Spring Batch,这需要一个子类,因为 JIRA BATCH-1867

public class IndentingStaxEventItemWriter<T> extends StaxEventItemWriter<T> 

  @Setter
  @Getter
  private boolean indenting = true;

  @Override
  protected XMLEventWriter createXmlEventWriter( XMLOutputFactory outputFactory, Writer writer) throws XMLStreamException 
    if ( isIndenting() ) 
      return new IndentingXMLEventWriter( super.createXmlEventWriter( outputFactory, writer ) );
    
    else 
      return super.createXmlEventWriter( outputFactory, writer );
    
  


但这需要额外的依赖,因为 Spring Batch 不包含缩进 StAX 输出的代码:

<dependency>
  <groupId>net.java.dev.stax-utils</groupId>
  <artifactId>stax-utils</artifactId>
  <version>20070216</version>
</dependency>

【讨论】:

我试过这个,但是当我在 weblogic 上部署我的应用程序并运行作业时,它会创建一个带有 的 xml 文件在结束标记之后的每一行中。如何避免这种情况?

以上是关于Java 中的 StAX XML 格式的主要内容,如果未能解决你的问题,请参考以下文章

xml解析之stax

XML编程总结——目录

StaX:序言中不允许的内容

XML编程总结——使用StAX接口操作xml

Java stax:对实体“R”的引用必须以“;”结尾分隔符

java中如何自定义xml文件中的xml格式