有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java:处理大型XML文件提取数据而不编写状态自动机?

我在Java XML处理方面没有经验。我的同事很快就在JAXP SAX解析器上实现了,这样大的XML就不会加载到内存中,我们就在流上操作。这意味着我们使用以下方法实现了回调接口:

public void startElement(..., String elementName, ...){ ... }
public void characters(char [] buf, int offset, int len) { ... }

实现维护由元素名和深度堆栈管理的标记层次结构中当前位置的状态

每个startElement/endElement都装满了意大利面条if/case和寄存器回调,这些回调调用了characters方法来决定需要和算法如何提取以及在何处保存新的部分处理数据。此代码由过滤逻辑生成。实际逻辑更大,但不是更难

在每个结束的第二级标记上,如果过滤器做出肯定的决定,我们将收集的数据传递到其他位置,清理当前上下文状态并开始处理另一部分数据

我们的逻辑是原始的-如果lvl2标签是person,并且子标签的顺序是:skills/skill/id,具有id的指定值-提取lvl3email标签值+lvl4标签值地址/城市

这个任务不是XPath,因为我们一次提取了几个类别,如果我正确理解XPath,它将在DOM上运行,并且不是面向流的

我看到了XSLT(一种面向流的语言)的可能用途,但似乎它的作用域——从一个XML文档生成另一个XML文档。可以通过XSLT处理器传递大型文档,用描述性XSLT源代码构建易于处理的XML,然后用SAX解析器处理结果数据。但这看起来像是一个糟糕的决定

使用描述性指令(更好地使用类似XPath的简化语法,从根目录定义标记顺序并检查标记/属性值)从规则结构的大型XML流中提取数据的Java技术是什么,何时提取,提取什么,以及提供回调扩展点以将提取的数据部分传递给其他用户处理

我的主要目标是通过以描述性的方式表达提取规则,使代码更易于维护,并避免编写自定义有限状态自动机来跟踪SAX解析器中的上下文


共 (1) 个答案

  1. # 1 楼答案

    SAX是旧的skool,正如您所指出的,在startElement回调中有很多逻辑

    StAX是流式解析器,我认为它更适合您的用例,因为它允许您从XML流中提取事件,因此不需要像DOM那样加载整个文档,并且您可以获得比SAX方法更多的XML语义支持。StAX被描述为here