我正在使用javax.xml.xpath
来搜索xml文件中的特定字符串,但由于需要搜索大量的xml文件,因此结果比预期慢得多。
java支持的api是否比javax.xml.xpath
更快或哪个是最快的?
答案 0 :(得分:10)
正如skaffman所指出的那样,您需要确保尽可能高效地使用javax.xml.xpath
库。如果您要执行XPath语句,则需要确保将其编译为XPathExpression
。
XPathExpression xPathExpression = xPath.compile("/root/device/modelname");
nl = (NodeList) xPathExpression.evaluate(dDoc, XPathConstants.NODESET);
<强>演示强>
在示例中,选项#2将比选项#1更快。
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
public class Demo {
public static void main(String[] args) {
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder builder = domFactory.newDocumentBuilder();
File xml = new File("input.xml");
Document dDoc = builder.parse(xml);
NodeList nl;
// OPTION #1
XPath xPath = XPathFactory.newInstance().newXPath();
nl = (NodeList) xPath.evaluate("root/device/modelname", dDoc, XPathConstants.NODESET);
printResults(nl);
nl = (NodeList) xPath.evaluate("/root/device/modelname", dDoc, XPathConstants.NODESET);
printResults(nl);
// OPTION #2
XPathExpression xPathExpression = xPath.compile("/root/device/modelname");
nl = (NodeList) xPathExpression.evaluate(dDoc, XPathConstants.NODESET);
printResults(nl);
nl = (NodeList) xPathExpression.evaluate(dDoc, XPathConstants.NODESET);
printResults(nl);
} catch (Exception e) {
e.printStackTrace();
}
}
private static void printResults(NodeList nl) {
for(int x=0; x<nl.getLength(); x++) {
System.out.println("the value is: " + nl.item(x).getTextContent());
}
}
}
<强> input.xml中强>
<?xml version="1.0" encoding="UTF-8"?>
<root>
<blah>foo</blah>
<device>
<modelname>xbox</modelname>
</device>
<blah>bar</blah>
<device>
<modelname>wii</modelname>
</device>
<blah/>
</root>
答案 1 :(得分:4)
我想知道XPath搜索是否真的是你的瓶颈,还是它实际上是XML解析?我会怀疑后者。我不知道您的XML文档是多么持久,但我认为解决方案是将它们存储在XML数据库中,这样您只需要产生一次解析成本,这样就可以将它们编入索引以使XPath / XQuery搜索更有效率
答案 2 :(得分:1)
你可以查看我之前的answer相关内容。
基本上我使用了JXpath和Xerces以及Dom4J和javax。 我可以从我的经验中充满信心地说VTD-XML是最快的选择。
如果你想搜索,还有很多其他关于在SO上使用VTD-XML的问题。
编辑:
好的,所以基于你的评论,代码片段将是这样的:
VTDGen vg = new VTDGen();
AutoPilot ap = new AutoPilot();
int i;
ap.selectXPath("/root/device/modelname");
if (vg.parseFile(PATH_TO_FILE,true)){
VTDNav vn = vg.getNav();
ap.bind(vn); // apply XPath to the VTDNav instance
// AutoPilot moves the cursor for you
while((i=ap.evalXPath())!=-1){
System.out.println("the value is: " + vn.toNormalizedString(vn.getText()));
}
}
对于以下XML:
<root>
<blah>foo</blah>
<device>
<modelname>xbox</modelname>
</device>
<blah>bar</blah>
<device>
<modelname>wii</modelname>
</device>
<blah/>
</root>
输出将是:
the value is: xbox
the value is: wii
你可以从这里拿走......
答案 3 :(得分:0)
你应该详细说明你要搜索的是什么类型的东西 - 如果它是简单的内容字符串,我会考虑使用Stax API(javax.xml.stream.XMLStreamReader)。 如果您需要限制搜索特定子集,则XPath很好。
XPath的一个问题是,依赖于表达式,它最终可能会在内存中构建一个DOM树,而且这在速度和内存使用方面都相当昂贵(相对于解析XML)。因此,如果可以避免这种情况,单独就可以加快3x工厂的处理速度。