for循环中的XPath求值始终从第一次迭代返回节点的值

时间:2016-07-29 16:17:51

标签: java xml xpath

我正在尝试使用在for循环中调用的方法从节点中提取值。

每次调用Method时,xpath.evaluate仅计算首次传入方法的原始节点。

- 示例节点

<doc>
  <str name="subcategory">xyzabc</str>
  <str name="type">QAs</str>
  <str name="id">1234</str>
</doc>

- 用于调用的循环

 ArrayList<Node> responseNodeList = parseResponse(*document as string*);   
 for(int k = 0;k<responseNodeList.size();k++){
                Result resultNode = new Result();

                resultNode.setUrl(new URL(getAttributeValue(responseNodeList.get(k),resultUrl)));
                resultNode.setId(new String(getAttributeValue(responseNodeList.get(k),resultId)));
}

- 我提取值的方法

private String getAttributeValue(final Node responseNodeUrl, String attribute) throws SearchException {
        try {   
        Node evalNode = null;
        evalNode = responseNodeUrl;

        try {
            nodelisttostr(responseNodeUrl); // This is what i am printing out the node.. where we dont have a problem
        } catch (TransformerFactoryConfigurationError e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (TransformerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }   

        XPath xPath = XPathFactory.newInstance().newXPath();
        XPathExpression expr = null;
         expr = xPath.compile("/doc/str[@name='"+attribute+"']");  
        String result ;
        result=(String) expr.evaluate(evalNode,XPathConstants.STRING);  
        xPath.reset();
        System.out.println("++++++++"+result); //But when i print this out, it always prints the same value

        return result;
    } catch (XPathExpressionException e) {
        log.error("Error in SearchEngine:getAttributeValue:: "+e.getMessage());
        throw new SearchException(e);
    }
}

2 个答案:

答案 0 :(得分:0)

解决..

XpathExpression总是拿起传递给该方法的第一个节点,由于某种原因,它似乎被缓存了,我将我的评估字符串改为看起来像expr = xPath.compile(".//str[@name='"+attribute+"']");,然后评估方法现在将当前视图文档。

谢谢大家。

答案 1 :(得分:-1)

如果在上面的XML上,您使用:

Thing

你会得到:

// Create a `ThingBase` class to "type-erase" `Thing`'s 
// template parameter. `ThingBase` should contain your
// `func`, as `virtual`.
struct ThingBase
{
    virtual void func();
};

// Your `Thing<T>` class should override `func`
template <typename T>
struct Thing : ThingBase
{
    void func() override { /* ... */ }
};

// Your `IService` now only needs to be as follows:
struct IService
{
    void func(ThingBase& x) 
    {
        x.func();
    }
};

如果您在XML上面的XPath表达式中使用//doc/str/@name ,即

Attribute='name="subcategory"'
Attribute='name="type"'
Attribute='name="id"'

然后你会得到:

contains

但我认为您只想用您的代码执行以下操作:

改变这个:

//doc/str/@name[contains(.,'e')]

即可添加额外的Attribute='name="subcategory"' Attribute='name="type"'

expr = xPath.compile("/doc/str[@name='"+attribute+"']"); 

评估所有节点而不是第一个节点。

我希望这有帮助!