XPath处理混合内容

时间:2011-09-22 16:27:20

标签: java xml xpath

如何通过XPath提取此类元素的文本:

<document>
  some text
     <subelement>subelement text</subelement>
  postscript
</document>

XPath表达式:

/document

返回文档节点文本及其所有子节点文本:

some text         subelement text    postscript

XPath表达式:

/document/text()

只返回第一个文本节点:

some text

即缺少“postscript”。

问题
有没有办法获得<document>的直接儿子的所有文本节点的文本?

后记
非常专注的示例,如果您想自己测试,请复制到主方法并修复导入。

    DocumentBuilder dbuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();

    String xml = "<?xml version='1.0' encoding='UTF-8'?>" +
                 "<document>"
                 + "some text into document"
                 + "    <subelement>"
                 + "        some text into SUBelement"
                 + "    </subelement>"
                 + "POSTSCRIPT"
                 + "</document>";

    //i'm forced to use an InputSource because parse doesn't take readers directly :-(
    Document doc = dbuilder.parse(new InputSource(new StringReader(xml)));

    //usual way to get an xpath
    XPath xp = XPathFactory.newInstance().newXPath();

    System.out.println(xp.evaluate("/document", doc));

    System.out.println(xp.evaluate("/document/text()",doc));

4 个答案:

答案 0 :(得分:2)

刚刚测试

xp.evaluate("/document/text()",doc, XPathConstants.NODESET)

确实会返回所有文本子项,但您正在执行

xp.evaluate("/document/text()", doc, XPathConstants.STRING)

似乎只将节点集中的第一个节点转换为String。所以也许你需要找到另一种方法将NodeSet转换为String。

答案 1 :(得分:2)

这将为您提供所有文本孩子。通常,依赖于toString()或尝试返回String表示的方法将导致在处理DOM时出现问题。 “完全做好/做得对”总是更安全。

        NodeList list = (NodeList) xp.evaluate("/document/text()", doc, XPathConstants.NODESET);
        for (int i = 0; i < list.getLength(); i++) {
            System.out.println(list.item(i).getNodeValue());
        }

答案 2 :(得分:1)

XPath /document/text()将返回document元素的所有子文本节点。在您的示例中:some textpostscript。我认为(我不知道Java类)System.out.println会自动将节点集转换为字符串表示形式,在这种情况下它只返回第一个节点。

答案 3 :(得分:1)

  

XPath表达式:

/document/text()
     

只返回第一个文本节点:

some text into document
     

即缺少“postscript”。

上面的XPath表达式返回/document的所有文本节点子节点,但XPath.evaluate() method, with no 3rd argument将其结果转换为字符串。 在这个过程中,它看起来像<xsl:value-of>,因为它只转换结果节点集中的第一个节点。

要打印所有文本节点子节点的值,请提供XPathConstants.NODESET作为XPath.evaluate()的第3个参数。这将为您提供文本节点的节点集NodeList。然后你可以遍历它们并打印每一个。或者您可以尝试将NodeList直接传递给println(),并查看它打印的内容。 : - )