如何有效地编写xml数据库文件?

时间:2011-01-26 19:10:53

标签: java xml database file jaxp

我想将XML文件构建为数据存储区。看起来应该是这样的:

<datastore>
    <item>
        <subitem></subitem>
        ...
        <subitem></subitem>
    </item>
    ....
    <item>
        <subitem></subitem>
        ...
        <subitem></subitem>
    </item>
</datastore>

在运行时,我可能需要将项添加到数据存储区。项目数可能很高,因此我不想将整个文档保存在内存中,也不能使用DOM。我只想写一个发生变化的部分。 或DOM是否支持此功能?

我第一次看StAX,但我不确定它是否符合我的要求。

在根元素关闭之前,记住文件末尾的光标位置不是最好的吗?这始终是添加新项目的位置。因此,如果我记得这个位置并在更改期间保持最新,我可以在最后添加一个新项目,而不会遍历整个文件。

也许第二个游标可以从第一个游标中独立使用,只是为了阅读而迭代文档。

我看不出StAX是否支持这一点,是吗?

是否存在基于块的API文件而不是流基础?块文件“设备”不是文件和文件系统的典型示例吗?如果有这样的API,它对我的​​问题有帮助吗?

提前致谢。

4 个答案:

答案 0 :(得分:1)

更新XML基本上是不可能的,因为没有“廉价”的方式来插入数据。

附加XML并不是那么糟糕。你需要做的就是寻找文件的末尾,然后回到“结束标记”(在这种情况下是&lt; / datastore&gt;),然后开始写。这是一个廉价的操作,但是没有一个框架能够真正支持这一点,因为它们主要用于处理格式良好的全船XML文档,整体而言不是碎片。

您可以使用类似StAX的东西,但在这种情况下,StAX不知道&lt; datastore&gt;标签,而不是它只是知道&lt; item&gt;标签及其元素。然后你创建Items并开始一遍又一遍地写入你设置的同一个OutputStream。

这是最好的方法。

但是如果您需要删除或更改数据,那么您可以重写内容,或者做一些黑客行为,例如将元素标记为“非活动”,在XML文件中搜索它们,寻找'active =“Y” '属性,然后就地将Y更改为N.它可以完成,它将大部分都是高效的,但它远远超出普通XML处理框架允许的范围。如果我这样做,我会阅读整个文件并跟踪这些条目并在其中记下它们的位置,以便稍后我可以轻松地有效地寻找和更改它们。

然后,当您更新某些内容时,您将“取消激活”旧内容,并“追加”新内容。最终通过重写所有内容并抛出旧的“非活动”条目来获取GC文件。

答案 1 :(得分:1)

根据经验,XML文件作为数据存储的效率不高,不适用于您似乎想要使用它们的基于记录的数据。

但是如果你已经有了这个文件并且绝对无法做任何事情,你可以使用StAX XMLEventReaderXMLEventWriter来快速读取文件并插入/修改元素在它。

但是当我快速说出来时,我的意思是比DOM更快,但远不及任何关系数据库那么有效。

更新:您可以考虑的另一个选项是vtd-xml,虽然我没有在实际项目中尝试过,但它实际上看起来相当不错。

答案 2 :(得分:0)

如果您总是想在最后添加项目,那么处理此问题的最佳方法是拥有两个XML文件。外部的一个datstore.xml只是一个包装器,如下所示:

<!DOCTYPE datastore [
  <!ENTITY e SYSTEM "items.xml">
]>
<datastore>&e;</datastore>

文件items.xml如下所示:

<item>....</item>
<item>....</item>
<item>....</item>

没有包装元素。

如果要附加数据,可以打开items.xml并写入其末尾。如果要读取数据,请使用XML解析器打开datastore.xml。

当然,一旦您的数据增长超过20Mb左右,使用XML数据库可能会更好。但是我多年来一直使用这种方法来记录Saxon订单,目前文件大约是8Mb,而且工作正常。

答案 3 :(得分:0)

部分更新XML文件并不是非常简单或有效,因此作为用例,您将不会获得太多支持。

听起来你需要一个合适的数据库,或许还有一个工具可以将数据导出为XML。

如果您不想使用数据库并坚持将数据完全存储为XML,则可以考虑将所有项目作为对象保留在内存中。每当添加新的时,您都可以将所有这些内容写入XML。它似乎效率低下,但根据您的数据大小可能仍然足够好。

如果选择此路径,您可能需要查看Xstream库以使其变得非常简单,请参阅stream tutorial以获取快速示例。