SAX解析器可以在Java中使用XPath吗?

我正在尝试迁移我的一个类,它使用带有大量XPath表达式的DOM解析来进行SAX解析。 DOM解析对我来说很好,但是我尝试解析的一些文件太大而导致服务器超时。 我想重用XPathSAX解析,但我不确定是否可能,如果不可能,请你帮助我,因为我不知道当我只使用SAX时,以下代码将如何:

 Document doc = bpsXml.getDocument(); String supplierName = BPSXMLUtils.getXpathString(doc, "/Invoice/InvoiceHeader/Party[@stdValue='SU']/Name/Name1"); String language = BPSXMLUtils.getXpathString(doc, "/Invoice/InvoiceHeader/InvoiceLanguage/@stdValue"); 

简单地使用SAX解析器不会在内存中构建XML树的表示(这就是为什么SAX更具内存效率)。 只有遇到新的XML元素时,它才会触发“事件”。 您必须在内存中保留上下文(通常是一堆父元素)以“知道”您在树中的位置。

由于您在内存中没有树,因此您将无法使用XPath。 您只能测试当前的“上下文”(您的手动管理堆栈)来查询您的文档。记住SAX解析器只会对您的文件执行一次运行,因此文件中的顺序很重要。

幸运的是,还有其他方法,如VTD-XML ,它是一个在内存中构建XML树的库,但只有结构部分,它不从文件中提取实际内容,根据需要提取内容。 它仍然允许XPath,它比DOM解析器更高效。 我个人在工作时使用这个库用XPath解析~700MB的XML文件(是的,这很疯狂,但它很有效,而且非常快。)

恕我直言,处理XML的最简单方法是使用StAX ,即XML的Streaming API。 它结合了DOM和SAX的优点(并且更容易向您迁移)。 您仍然有一个光标到XML元素(如在SAX中),但您的代码会向前移动光标。 这提供了XML处理代码变得更具可读性的巨大优势。 它还解决了内存问题,因为只有当前的XML元素必须保存在内存中。 这里也是一个很好的教程 。

还要回答你原来的问题:谷歌的一个简短搜索向我展示了没有简单,广泛接受的方式,这可能意味着所有自定义解决方案都不健壮,没有维护,也没有经过充分测试。

切换到SAX解析(或StAX)将需要完全改变您的方法。 看起来好像你还没有完全理解它会有多少工作。 对于任何有意义的建议,我们需要知道文件有多大,以及您希望对数据进行何种处理。 例如,如果要过滤数据,那么使用文档投影的XQuery实现可能是一个很好的答案(这将在后台自动使用SAX来构建仅包含您实际感兴趣的数据子集的树) 。