0

我有一个大型 SOAP 响应,我想处理并存储在数据库中。我正在尝试将整个内容作为文档处理,如下所示

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setCoalescing(true);
DocumentBuilder db = dbf.newDocumentBuilder();
InputStream is = new ByteArrayInputStream(resp.getBytes());
Document doc = db.parse(is);
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
XPathExpression expr = xpath.compile(fetchResult);
String result = (String) expr.evaluate(doc, XPathConstants.STRING);

resp 是 SOAP 响应, fetchResult 是 String fetchResult = "//result/text()";

使用这种方法,我会出现内存不足的异常。所以我试图将文档作为流来处理,而不是将整个响应作为文档来使用。

但我想不出代码。

你们中的任何人都可以帮我吗?

4

3 回答 3

1

DOM 和 JDOM 是消耗内存的解析 API。DOM 在内存中创建 XML 文档树。您应该使用 StAX 或 SAX,因为它们提供了更好的性能。

于 2013-06-20T08:25:29.463 回答
1

如果这是在 Java 中,您可以尝试使用dom4j。这有一种使用 xpathExpression 读取 xml 的好方法。

此外,dom4j 提供了一个基于事件的模型来处理 XML 文档。使用这种基于事件的模型,我们可以在成功处理部分文档时修剪 XML 树,而不必将整个文档保存在内存中。

如果您需要处理由某个数据库进程在外部生成的非常大的 XML 文件,该文件类似于以下内容(其中 N 是一个非常大的数字)。

<ROWSET>
    <ROW id="1">
        ...
    </ROW>
    <ROW id="2">
        ...
    </ROW>
    ...
    <ROW id="N">
        ...
    </ROW>
</ROWSET>

因此,要单独处理每个<ROW>,您可以执行以下操作。

// enable pruning mode to call me back as each ROW is complete
SAXReader reader = new SAXReader();
reader.addHandler( "/ROWSET/ROW", 
    new ElementHandler() {
        public void onStart(ElementPath path) {
            // do nothing here...    
        }
        public void onEnd(ElementPath path) {
            // process a ROW element
            Element row = path.getCurrent();
            Element rowSet = row.getParent();
            Document document = row.getDocument();
            ...
            // prune the tree
            row.detach();
        }
    }
);

Document document = reader.read(url);

// The document will now be complete but all the ROW elements
// will have been pruned.
// We may want to do some final processing now
...

请参阅dom4j 如何处理非常大的 XML 文档?了解它是如何工作的。


此外,dom4j 通过 JAXP 与任何 SAX 解析器一起工作。有关更多详细信息,请参阅dom4j 使用什么 XML 解析器?

于 2013-06-20T08:11:58.230 回答
0

XPath 和 XPathExpression 类具有接受 InputSource 参数的方法。

InputStream input = ...;
InputSource source = new InputSource(input);

XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
XPathExpression expr = xpath.compile("...");
String result = (String) expr.evaluate(source, XPathConstants.STRING);
于 2013-06-20T08:50:39.653 回答