使用SAX和Java生成XML

有人知道使用SAX框架(或类似的东西)和Java编写XML的好教程(或有一个很好的例子)吗? 搜索在有用结果方面收效甚微。 我正在尝试从Android应用程序导出,并希望避免尽可能多的内存开销。

有一种非常有用的技术可以通过SAX框架直接从POJO 生成 XML(不是SAX解析器,而是SAX框架)。 该技术可用于生成XML文档

从任意数据结构生成XML
http://download.oracle.com/javaee/1.4/tutorial/doc/JAXPXSLT5.html

本质上,您为POJO添加方法或为POJO编写实用程序类,将它们转换为SAX事件发射器(在解析XML文档时通常会发出SAX解析器等事件)。 现在,您的“SAX事件生成器”看起来像SAX解析器的输出端,并且可以被赋予SAX解析器将采用的任何内容处理程序,例如pretyy打印XML的内容处理程序。 但它也可以提供给DOM解析器以生成DOM树或提供给XSLT引擎以生成HTML或执行真正的XSL转换,而无需首先从POJO生成中间XML文档。

例如,Person类可能有一个包含以下行的emitXML()方法:

 handler.startElement(nsu, PERSON_TAG, PERSON_TAG, NO_ATTRIBUTES); handler.startElement(nsu, FIRSTNAME_TAG, FIRSTNAME_TAG, atts); handler.characters(this.firstName.toCharArray(), 0, this.firstName.length()); handler.endElement(nsu, FIRSTNAME_TAG, FIRSTNAME_TAG); ... emit more instance variables ... emit child object like: homeAddress.emitXML(handler, ...); handler.endElement(nsu, PERSON_TAG, PERSON_TAG); 

更新:

其他几个参考:


对评论的几点回应:

这是事实,但上面描述的XMLStreamWriter接口更加用户友好。 – Michael Kay 3小时前

是的,但我想我不清楚。 我可以轻松遍历层次结构并使用XMLStreamWriter直接将XML文档输出到流。 但是,这些文章展示了一种强大的技术来遍历层次结构并生成SAX事件,而不是直接输出XML文档。 现在我可以插入不同内容处理程序,这些处理程序可以执行不同的操作或生成不同版本的XML。 我们还可以将对象层次结构提供给任何接受SAX解析器的工具,例如XSLT引擎。 它实际上只是利用了SAX框架建立的访问者模式:我们将遍历层次结构与输出XML分开。 输出XML的部分(内容处理程序)当然应该使用XMLStreamWriter如果它们的目的是编写XML流。

例如,在我们的程序中,我们通过分布式组件之间的网络套接字发送XML消息,我们还使用XSLT生成HTML页面。 以前,我们遍历我们的层次结构以生成XML文档(字符串),然后将该XML文档写入网络套接字或将该文档提供给XSLT引擎(基本上只是再次解析它)。 使用这种技术后,我们基本上可以将对象层次结构(使用此SAX适配器)直接提供给XSLT引擎,而无需中间XML字符串。 能够使用一个内容处理程序为网络流生成紧凑的XML表示并使用另一个生成用于写入日志文件的漂亮打印的XML文档也很方便。

此外,使用SAX解析器API来编写XML是对API的误用,恕我直言。 – Puce 49分钟前

或许,但我认为这取决于您的需求。 如果OP的要求只是写出一个特定的XML文档,那么这肯定是矫枉过正的。 但是,我认为值得一提的是,如果OP在他的项目中以其他方式使用XML而他没有提及。 推销另类想法没有坏处。

称其滥用可能有点强烈,但我同意您有权获得您的意见。 它记录在Oracle教程中,因此不被Sun / Oracle工程师视为滥用。 我们的项目非常成功,可以帮助我们满足我们的要求而没有明显的缺点,因此我将在我的工具箱中保留这种方法,以便将来有用。

SAX解析用于读取文档,而不是编写文档。

您可以使用XMLStreamWriter编写XML:

 OutputStream outputStream = new FileOutputStream(new File("doc.xml")); XMLStreamWriter out = XMLOutputFactory.newInstance().createXMLStreamWriter( new OutputStreamWriter(outputStream, "utf-8")); out.writeStartDocument(); out.writeStartElement("doc"); out.writeStartElement("title"); out.writeCharacters("Document Title"); out.writeEndElement(); out.writeEndElement(); out.writeEndDocument(); out.close(); 

下面回答“使用SAX解析器和Java编写XML的好教程”部分问题

我不确定你是否经历过这个。 但我真的很喜欢Java真正的大指数 。

仔细阅读: http : //download.oracle.com/javase/tutorial/jaxp/index.html

最后,这个: http : //download.oracle.com/javase/tutorial/jaxp/sax/index.html

请参阅我的个人博客文章: Java生成在Java中 – 特别是SAX方法 。 它引用了一些与此相关的文章,提供了一个具体的例子,并将SAX与其他流行的API进行了比较,以便从Java生成XML。

(意识到这是一个较旧的问题,但认为有必要为可能有同样问题的其他人添加此问题。)

还要考虑JAXB来编写/读取XML。

您还可以通过以下方式与trax建立联系:

 public abstract class PipedSAXSource extends SAXSource { protected PipedSAXSource() { setXMLReader(new CallWriteDuringSax()); } protected abstract void writeTo(ContentHandler sink) throws IOException, SAXException; private class CallWriteDuringSax extends XMLFilterImpl { @Override public void parse(InputSource ignored) throws IOException, SAXException { writeTo(getContentHandler()); } @Override public void setFeature(String name, boolean value) {} } } 

使用如下:

  public static void main(String[] args) throws Exception { Source in = new PipedSAXSource() { @Override protected void writeTo(ContentHandler sink) throws SAXException { sink.startDocument(); sink.startElement("", "root", "root", new AttributesImpl()); sink.endElement("", "root", "root"); sink.endDocument(); } }; Transformer identity = TransformerFactory.newInstance().newTransformer(); identity.transform(in, new StreamResult(System.out)); }