为什么Javax'当选择器使用text()节点测试时,XPath evaluate()方法不返回具有非中断空格的元素

时间:2017-06-08 13:26:38

标签: java xpath javax

我有以下Java代码

    @Test
    public void notGettingNonBreakingSpace() throws ParserConfigurationException, IOException, SAXException, XPathExpressionException {
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        documentBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);

        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();

        String html = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
            "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \n" +
            "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n" +
            "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n" +
            "<body><table><tr><td>&nbsp;</td></tr></table></body>\n" +
            "</html>";

        Document document = documentBuilder.parse(new ByteArrayInputStream(html.getBytes()));
        XPath xpath = XPathFactory.newInstance().newXPath();
        int result = ((NodeList) xpath.evaluate("//tr/td/text()", document, XPathConstants.NODESET)).getLength();
        assertEquals(1, result);
    }

断言失败,因为result0。但是,如果我使用HTML,请将其保存为.htm文件,然后在Chrome中打开它,开发人员工具控制台中的$x("//tr/td/text()")按预期返回:

[text]
> 0: text
  length: 1
> __proto__: Array(0)

我需要做些什么才能在Java中获得相同的结果,即包含一个项目的节点列表?

是否有&#34;忽略空白&#34;在某个地方设置DocumentBuilder或XPath对象,或者是Java和Chrome的JS引擎不同意如何处理这个特殊空白字符的根本原因?

注意:删除text()(即文本节点选择)有效;然后它返回正确的结果。用实际文本(例如&nbsp;)替换不间断空格(foo)也有效......

1 个答案:

答案 0 :(得分:1)

看起来Java在禁用dtd加载时无法识别&nbsp;

您的问题可以通过在html中为&nbsp;编写实体来解决,例如:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" [ <!ENTITY nbsp "&#160;"> ]>

评估现在提供一个文本节点。