首页
学习
活动
专区
工具
TVP
发布

加速xpath
EN

Stack Overflow用户
提问于 2010-03-03 01:24:33
回答 5查看 16.9K关注 0票数 19

我有一个1000条目文档,它的格式类似于:

代码语言:javascript
复制
<Example>
     <Entry>
          <n1></n1>
          <n2></n2>
      </Entry>
      <Entry>
          <n1></n1>
          <n2></n2>
      </Entry>
      <!--and so on-->

这里有1000多个入口节点。我正在写一个Java程序,它基本上是一个接一个地获取所有节点,并对每个节点进行一些分析。但问题是节点的检索时间随着节点个数的增加而增加。例如,检索第一个节点需要78毫秒,检索第二个节点需要100毫秒,而且还在不断增加。检索999节点需要5秒以上的时间。这是非常慢的。我们将把这段代码插入到XML文件中,这些文件甚至有1000多个条目。有些人像数百万人。解析整个文档的总时间超过5分钟。

我正在使用这个简单的代码来遍历它。这里的nxp是我自己的类,它包含从xpath获取节点的所有方法。

代码语言:javascript
复制
nxp.fromXpathToNode("/Example/Entry" + "[" + i  + "]", doc);    

doc是该文件的文档。i是要检索的节点的编号。

同样,当我尝试这样的事情时

代码语言:javascript
复制
List<Node> nl = nxp.fromXpathToNodes("/Example/Entry",doc);  
      content = nl.get(i);    

我面临着同样的问题。

任何人都有任何关于如何加速节点竞争对手的解决方案,所以从XML文件中获得第一个节点和1000个节点所需的时间是相同的。

下面是xpathtonode的代码。

代码语言:javascript
复制
public Node fromXpathToNode(String expression, Node context)  
{  
    try  
    {  
        return (Node)this.getCachedExpression(expression).evaluate(context, XPathConstants.NODE);  
    }  
    catch (Exception cause)  
    {  
        throw new RuntimeException(cause);  
    }  
}  

下面是fromxpathtonodes的代码。

代码语言:javascript
复制
public List<Node> fromXpathToNodes(String expression, Node context)  
{  
    List<Node> nodes = new ArrayList<Node>();  
    NodeList results = null;  
    
    try  
    {  
        results = (NodeList)this.getCachedExpression(expression).evaluate(context, XPathConstants.NODESET);  
          
        for (int index = 0; index < results.getLength(); index++)  
        {  
            nodes.add(results.item(index));  
        }  
    }  
    catch (Exception cause)  
    {  
        throw new RuntimeException(cause);  
    }  
    
    return nodes;  
}  

这就是开始

代码语言:javascript
复制
public class NativeXpathEngine implements XpathEngine  
{      
private final XPathFactory factory;  
  
private final XPath engine;  

/**
 * Cache for previously compiled XPath expressions. {@link XPathExpression#hashCode()}
 * is not reliable or consistent so use the textual representation instead.
 */  
private final Map<String, XPathExpression> cachedExpressions;  
  
public NativeXpathEngine()  
{
    super();  
    
    this.factory = XPathFactory.newInstance();  
    this.engine = factory.newXPath();  
    this.cachedExpressions = new HashMap<String, XPathExpression>();  
}  
EN

回答 5

Stack Overflow用户

发布于 2010-08-10 20:18:03

试试VTD-XML。它比DOM使用更少的内存。它比SAX更容易使用,并且支持XPath。以下是一些示例代码,可帮助您入门。它应用XPath来获取Entry元素,然后打印出n1和n2子元素。

代码语言:javascript
复制
final VTDGen vg = new VTDGen();
vg.parseFile("/path/to/file.xml", false);

final VTDNav vn = vg.getNav();
final AutoPilot ap = new AutoPilot(vn);
ap.selectXPath("/Example/Entry");
int count = 1;
while (ap.evalXPath() != -1) {
    System.out.println("Inside Entry: " + count);

    //move to n1 child
    vn.toElement(VTDNav.FIRST_CHILD, "n1");
    System.out.println("\tn1: " + vn.toNormalizedString(vn.getText()));

    //move to n2 child
    vn.toElement(VTDNav.NEXT_SIBLING, "n2");
    System.out.println("\tn2: " + vn.toNormalizedString(vn.getText()));

    //move back to parent
    vn.toElement(VTDNav.PARENT);
    count++;
}
票数 10
EN

Stack Overflow用户

发布于 2013-02-27 08:55:14

正确的解决方案是在调用item(i)之后立即分离节点,如下所示:

代码语言:javascript
复制
Node node = results.item(index)
node.getParentNode().removeChild(node)
nodes.add(node)

请参阅XPath.evaluate performance slows down (absurdly) over multiple calls

票数 7
EN

Stack Overflow用户

发布于 2012-03-12 20:05:21

我在Xpath评估中遇到了类似的问题,我尝试使用CachedXPathAPI,它比之前使用的XPathApi快100倍。此处提供了有关此Api的更多信息:http://xml.apache.org/xalan-j/apidocs/org/apache/xpath/CachedXPathAPI.html

希望能有所帮助。干杯,Madhusudhan

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2365208

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档