Java 大文件情况下的Xpath方法

Java 大文件情况下的Xpath方法,java,xml,xpath,Java,Xml,Xpath,您现在将看到的类是在Java中通过XPath解析XML文档的经典方法: public class Main { private Document createXMLDocument(String fileName) throws Exception { DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); domFactory.setNamespaceAware

您现在将看到的类是在Java中通过XPath解析XML文档的经典方法:

public class Main {

    private Document createXMLDocument(String fileName) throws Exception {
        DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
        domFactory.setNamespaceAware(true);
        DocumentBuilder builder = domFactory.newDocumentBuilder();
        Document doc = builder.parse(fileName);

        return doc;
    }

    private NodeList readXMLNodes(Document doc, String xpathExpression) throws Exception {
        XPath xpath = XPathFactory.newInstance().newXPath();
        XPathExpression expr = xpath.compile(xpathExpression);

        Object result = expr.evaluate(doc, XPathConstants.NODESET);
        NodeList nodes = (NodeList) result;

        return nodes;
    }

    public static void main(String[] args) throws Exception {
        Main m = new Main();
        Document doc = m.createXMLDocument("tv.xml");
        NodeList nodes = m.readXMLNodes(doc, "//serie/eason/@id");
        int n = nodes.getLength();

        Map<Integer, List<String>> series = new HashMap<Integer, List<String>>();

        for (int i = 1; i <= n; i++) {
            nodes = m.readXMLNodes(doc, "//serie/eason[@id='" + i + "']/episode/text()");
            List<String> episodes = new ArrayList<String>();
            for (int j = 0; j < nodes.getLength(); j++) {
                episodes.add(nodes.item(j).getNodeValue());
            }
            series.put(i, episodes);
        }

        for (Map.Entry<Integer, List<String>> entry : series.entrySet()) {
            System.out.println("Season: " + entry.getKey());
            for (String ep : entry.getValue()) {
                System.out.println("Episodio: " + ep);
            }
            System.out.println("+------------------------------------+");
        }
    }
}

我很担心,因为我需要处理的xml文档是由客户创建的,在里面你基本上可以有无限数量的记录来描述电子邮件及其内容,每个用户都有自己的个人电子邮件,所以里面有很多html。我知道这不是最聪明的方法,但这是一种可能性,在我来到这里之前,它已经开始运行了


我的问题是:如何使用xpath解析和计算大型xml文件?

您可以使用StAX解析器。它将比DOM选项占用更少的内存。关于StAX的一个很好的介绍是

您可以使用StAX解析器。它将比DOM选项占用更少的内存。StAX的一个很好的介绍是

首先,XPath不解析XML。您的createXMLDocument方法就是这样做的,它生成解析XML的树表示作为输出。然后使用XPath搜索树表示

您真正需要的是在解析XML时动态搜索XML的东西

一种方法是使用实现文档投影的XQuery系统,例如Saxon EE。这将分析您的查询以查看文档的哪些部分是需要的,当您解析文档时,它将构建一个只包含文档中实际需要的部分的树


但是,如果查询与示例中的查询一样简单,那么将其编码为SAX应用程序就不难了,在SAX应用程序中,XML解析器会向应用程序通知startElement和endElement等事件,而无需在内存中构建树。

首先,XPath不会解析XML。您的createXMLDocument方法就是这样做的,它生成解析XML的树表示作为输出。然后使用XPath搜索树表示

您真正需要的是在解析XML时动态搜索XML的东西

一种方法是使用实现文档投影的XQuery系统,例如Saxon EE。这将分析您的查询以查看文档的哪些部分是需要的,当您解析文档时,它将构建一个只包含文档中实际需要的部分的树


但是,如果查询与示例中的查询一样简单,那么将其编码为SAX应用程序就不难了,在SAX应用程序中,XML解析器会向应用程序通知startElement和endElement等事件,而无需在内存中构建树。

您使用什么库进行XML解析?你可能想看看stax parserI还没有决定什么…这就是为什么我要问的原因。那么stax是个好主意。因为它是一个串行解析器,而不是DOM,所以处理大文件需要的内存更少。我已经读过了。但这不是XPath。看起来您需要编写大量的if..else。这是真的,但它在内存方面更轻。您使用什么库进行XML解析?你可能想看看stax parserI还没有决定什么…这就是为什么我要问的原因。那么stax是个好主意。因为它是一个串行解析器,而不是DOM,所以处理大文件需要的内存更少。我已经读过了。但这不是XPath。看起来你需要写很多if..else。这是真的,但它在内存方面更轻模式非常简单。问题是,在某一点上,我将查询/delivery/recipients/new\u recipient之类的内容。我会有一大堆新的_接收者,一些客户有大约30万个3GB大小的接收者。我想要一个系统,允许我请求一个特定的查询,但像流一样读取它,这样我就可以控制内存过载。问题是,在某一点上,我将查询/delivery/recipients/new\u recipient之类的内容。我会有一大堆新的_接收者,一些客户有大约30万个3GB大小的接收者。我想要一个系统,允许我要求一个特定的查询,但读取它像一个流,所以我可以控制内存过载。
Document doc = builder.parse(fileName);

return doc;
  Object result = expr.evaluate(doc, XPathConstants.NODESET);
  NodeList nodes = (NodeList) result;

  return nodes;