我正在尝试迁移我的一个类,它使用DOM
解析和许多XPath
表达式来解析SAX
。 DOM
解析对我有好处,但我尝试解析的一些文件太大而导致服务器超时。我想重用XPath
和SAX
解析,但我不确定是否可能,如果不可能,请你帮助我,因为我不知道以下代码将如何仅使用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");
答案 0 :(得分:4)
简单地使用SAX解析器不会在内存中构建XML树的表示(这就是为什么SAX更具内存效率)。只有遇到新的XML元素时,它才会触发“事件”。您必须在内存中保留上下文(通常是一堆父元素)以“知道”您在树中的位置。
由于内存中没有树,因此无法使用XPath。您只能测试当前的“上下文”(您的手动管理堆栈)来查询您的文档。记住SAX解析器只会对您的文件执行一次运行,因此文件中的顺序非常重要。
幸运的是,还有其他方法,如VTD-XML,它是一个在内存中构建XML树的库,但只有结构部分,它不从文件中提取实际内容,内容被提取为 - 需要。它仍然允许XPath,它比DOM解析器更高效。我个人在工作中使用这个库用XPath解析~700MB的XML文件(是的,这很疯狂,但它的工作原理非常快。)
答案 1 :(得分:1)
IMHO处理XML的最简单方法是使用StAX,即XML的Streaming API。它结合了DOM和SAX的优点(并且更容易向您迁移)。您仍然有一个光标到XML元素(如在SAX中),但您的代码会向前移动光标。这提供了XML处理代码变得更易读的巨大优势。它还解决了内存问题,因为只有当前的XML元素必须保存在内存中。这也是一个不错的tutorial。
还要回答您的原始问题:Google上的简短搜索向我展示了没有简单,广泛接受的方式,这可能意味着所有自定义解决方案都不健全,不经过维护且未经过充分测试。
答案 2 :(得分:0)
切换到SAX解析(或StAX)将需要对您的方法进行彻底更改。看起来好像你还没有完全理解它将会有多少工作。对于任何有意义的建议,我们需要知道文件有多大,以及您希望对数据进行何种处理。例如,如果要过滤数据,那么使用文档投影的XQuery实现可能是一个很好的答案(这将在幕后自动使用SAX来构建仅包含您实际感兴趣的数据子集的树)