为什么Java中的XPath表达式会返回太多孩子?

时间:2009-03-27 22:10:06

标签: java xpath

我有以下xml文件:

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<config>
 <a>
  <b>
   <param>p1</param> 
   <param>p2</param> 
  </b>
 </a>
</config>

和获取我的节点参数的xpath代码:

Document doc = ...;
XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression expr = xpath.compile("/config/a/b");
Object o = expr.evaluate(doc, XPathConstants.NODESET);
NodeList list = (NodeList) o;

但事实证明节点列表(列表)有5个孩子,包括"\t\n",而不是只有两个。我的代码有问题吗?我怎样才能得到我的两个节点?

谢谢!

5 个答案:

答案 0 :(得分:5)

当您选择/config/a/b/时,您正在选择 b的所有子项,其中包括三个文本节点和两个元素。也就是说,考虑到上面的XML,只显示有问题的片段:

<b>
 <param>p1</param> 
 <param>p2</param> 
</b>

第一个孩子是<b>之后和<param>p1 ...之后的文本(空白)。第二个孩子是第一个param元素。第三个子节点是两个param元素之间的文本(空白)。等等。 XML中不会忽略空格,尽管许多处理XML的形式都忽略它。

您有几个选择:

  1. 更改您的xpath表达式,使其仅选择Ted Dziuba建议的元素节点,或
  2. 循环返回的五个节点,只选择非文本节点。
  3. 你可以这样做:

    for (int i = 0; i < nodes.getLength(); i++) {
        if (nodes.item(i).getNodeType() != Node.TEXT_NODE) {
            System.out.println(nodes.item(i).getNodeValue());
        }
    }
    

    您可以使用节点类型仅选择元素节点,或删除文本节点。

答案 1 :(得分:4)

所以xpath看起来像: /config/a/b/*/text()。 并输出:

for (int i = 0; i < nodes.getLength(); i++) {
        System.out.println(nodes.item(i).getNodeValue());
    }

将如预期的那样:p1和p2

答案 2 :(得分:2)

怎么样

/config/a/b/*/text()/..

答案 3 :(得分:1)

import org.w3c.dom.*;

import javax.xml.xpath.*;

import javax.xml.parsers.*;

import java.io.IOException;

import org.xml.sax.SAXException;

public class TestClient_XPath {

    public static void main(String[] args) throws ParserConfigurationException,
            SAXException, IOException, XPathExpressionException {

        DocumentBuilderFactory domFactory = DocumentBuilderFactory
                .newInstance();
        domFactory.setNamespaceAware(true);
        DocumentBuilder builder = domFactory.newDocumentBuilder();

        Document doc = builder.parse("yourfile.xml");
        XPath xpath = XPathFactory.newInstance().newXPath();

        XPathExpression xPathExpression = xpath.compile("/a/b/c");

        Object res = xPathExpression.evaluate(doc);

        System.out.println(res.toString());
    }

}

Xalan和Xerces似乎嵌入在rt.jar中。

不要包含xerces和xalan libs。

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4624775

答案 4 :(得分:0)

我不确定但不应该 / config / a / b 只返回 b / config / a / b / param 应返回两个 param 节点...

问题的观点可能是问题吗?当然,您将返回结果节点及其所有子节点。所以你只需要看第一个元素,而不是它的子元素。

但我完全错了,因为我通常只是使用Xpath来浏览DOM树(HtmlUnit)。