如何以内存高效的方式将xml写入bean的网络流

时间:2011-04-05 10:58:59

标签: java xml memory xml-serialization jdom

编辑以更清楚地指定方案。

我必须写一个xml文件,信息来自几个 bean(甚至不是整个bean,其中一些是jsut子集),一些bean包含列表等等所以我不能只是给xstream一个根bean并让它写入xml。还有一些格式可能需要满足某些条件,但前一个问题是一个

现在我正在使用JDOM在内存中创建doc,最后我使用XMLOutputter将doc写入文件。

但我想写的bean可能有非常大的其他bean列表等,而且使用的内存可能非常高。

所以我怀疑在内存方面应该有更好的方法吗? 我已经使用xstream为较大的bean内部的某些bean创建了xml,并将它们作为Elements附加到JDOM。

我希望以同样的方式使用pull解析器解析xml的内存效率更高,同样可以应用于编写xml。

5 个答案:

答案 0 :(得分:1)

您是否尝试过xstream,一个xml序列化库?

答案 1 :(得分:1)

让我直截了当: 你从一棵豆树开始。您希望使用这些文档来构造一个遵循其结构但具有自己的语法/模式的XML文档,因此简单的bean XML序列化是不可能的......

如果是这样的话,Blaise Doughan推荐的JAXB是一个很好的建议。但是,如果您需要对XML格式进行更精细的控制,则需要执行一些高度特定的序列化,或者您希望在创建XML时删除一些bean引用以在执行期间允许垃圾收集,然后使用Streaming API XML(StAX)可能就是您所需要的。您可以使用它将XML构造编写到流中。

http://download.oracle.com/javase/6/docs/api/javax/xml/stream/package-summary.html

很抱歉,如果它不是你的意思。如果我弄错了,你能给我们一个小的使用场景吗?

答案 2 :(得分:0)

答案 3 :(得分:0)

使用JDOM会很困难,即使您想深入挖掘并编写自定义子类。 XMLOutputter类型假定它被赋予了一个可以遍历的完整树。为了节省内存,必须以某种方式安排,以便只存在当前的子树。砍掉已遍历的子树是完全可行的;但是如何推迟创建子树直到需要它们为止。所有这些都需要在子类XMLOutputter,您的专用元素和bean导航代码之间进行某种协调。可能不值得努力。

我,正如G_H所做的那样,建议将Stax,javax.xml.stream.XMLStreamWriter与您自己的“bean导航器”结合使用。

答案 4 :(得分:0)

偏见声明 - 我是EclipseLink JAXB (MOXy)潜在客户


使用EclipseLink JAXB (MOXy),您可以获得所需的格式。这将允许您消除JDOM片段以减少内存占用。

示例

假设我们的模型中有以下类(省略了访问器以节省空间):

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {

    private Address billingAddress;

    private Address shippingAddress;

}

JAXB制图

由于EclipseLink MOXy符合JAXB规范(JSR-222),因此默认情况下会生成以下文档:

<customer>
    <billingAddress/>
    <shippingAddress/>
</customer>

路径映射

如果您需要对XML进行细粒度控制,可以使用MOXy的@XmlPath扩展名。 按如下方式注释字段:

@XmlPath("contact-info/billing-address")
private Address billingAddress;

@XmlPath("contact-info/shipping-address")
private Address shippingAddress;

将导致生成以下XML:

<customer>
   <contact-info>
      <billing-address/>
      <shipping-address/>
   </contact-info>
</customer>

位置映射

XPath片段可以包含位置指示符:

@XmlPath("address[1]")
private Address billingAddress;

@XmlPath("address[2]")
private Address shippingAddress;

生成的XML将如下所示:

<customer>
   <address/>
   <address/>
</customer>

条件映射

@XmlPath("address[@type='billing']")
private Address billingAddress;

@XmlPath("address[@type='shipping']")
private Address shippingAddress;

结果XML将是:

<customer>
   <address type="billing"/>
   <address type="shipping"/>
</customer>

了解更多信息