您的解析代码可能工作正常,但您正在加载的数据量可能太大而无法保存在其中
ArrayList。
您需要某种流水线将数据传递到其实际目的地,而不必一次将所有数据都存储在内存中。
我有时针对这种情况所做的工作与以下类似。
创建用于处理单个元素的接口:
public interface PageProcessor { void process(Page page);}PageHandler通过构造函数将此实现提供给:
public class Read { public static void main(String[] args) { XMLManager.load(new PageProcessor() { @Override public void process(Page page) { // Obviously you want to do something other than just printing, // but I don't know what that is... System.out.println(page);} }) ; }}public class XMLManager { public static void load(PageProcessor processor) { SAXParserFactory factory = SAXParserFactory.newInstance(); try { SAXParser parser = factory.newSAXParser(); File file = new File("pages-articles.xml"); PageHandler pageHandler = new PageHandler(processor); parser.parse(file, pageHandler); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }}将数据发送到此处理器,而不是将其放在列表中:
public class PageHandler extends DefaultHandler { private final PageProcessor processor; private Page page; private StringBuilder stringBuilder; private boolean idSet = false; public PageHandler(PageProcessor processor) { this.processor = processor; } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { //Unchanged from your implementation } @Override public void characters(char[] ch, int start, int length) throws SAXException { //Unchanged from your implementation } @Override public void endElement(String uri, String localName, String qName) throws SAXException { // Elide pre not needing change } else if (qName.equals("page")){ processor.process(page); page = null; } } else { page = null; } }}当然,您可以使您的界面处理多条记录而不是仅处理一条记录,并将
PageHandler收集页面本地放在较小的列表中,并定期将列表发送出去进行处理并清除列表。
或者(也许更好),您可以实现
PageProcessor此处定义的接口,并在其中构建逻辑来缓冲数据并将其发送以进一步进行大块处理。



