0

我想用 XPath 阅读站点地图,但它不起作用。这是我的代码:

private void evaluate2(String src){
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setNamespaceAware(true); 
    try{
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(new ByteArrayInputStream(src.getBytes()));

        System.out.println(src);

        XPathFactory xp_factory = XPathFactory.newInstance();

        XPath xpath = xp_factory.newXPath();

        XPathExpression expr = xpath.compile("//url/loc");

        Object result = expr.evaluate(doc, XPathConstants.NODESET);


        NodeList nodes = (NodeList) result;

        System.out.println(nodes.getLength());


        for (int i = 0; i < nodes.getLength(); i++) {
            items.add(nodes.item(i).getNodeValue());
            System.out.println(nodes.item(i).toString()); 
        }         
    }catch(Exception e){
        System.out.println(e.getMessage());
    }
}

在我检索站点地图的远程源之前,它通过变量 src 传递给 evaluate2。并且System.out.println(nodes.getLength());显示 0 My xpath 查询正在工作,因为此查询在 PHP 中工作。您在我的代码中看到错误吗?

谢谢

4

3 回答 3

1

我认为输入有命名空间。因此,您必须为 xpath 对象初始化 namespaceContext 并使用前缀更改您的 xpath。即 //usr/loc 应该是 //ns:url/ns:loc 然后在命名空间对象中添加命名空间前缀绑定。

您可以找到与 apache common 一起可用的 NamespaceContext 实现。http://ws.apache.org/commons/util/apidocs/index.html ws-commons-utils

NamespaceContextImpl namespaceContextObj = new NamespaceContextImpl();
    nsContext.startPrefixMapping("ns", "http://sitename/xx");
xpath.setNamespaceContext(namespaceContextObj);

XPathExpression expr = xpath.compile("//ns:url/ns:loc");

如果您不知道即将到来的命名空间,您可以从它自己的文档中获取它们,但我怀疑它会有多大用处。这里有一些操作方法 http://www.ibm.com/developerworks/xml/library/x-nmspccontext/index.html

于 2012-12-20T19:09:18.217 回答
1

您使用可识别名称空间的解析器(就是这样做的)解析站点地图factory.setNamespaceAware(true),然后尝试使用不使用名称空间解析器(或引用任何名称空间)的 XPath 来访问它。

最简单的解决方案是将解析器配置为不支持命名空间。只要您只是解析一个独立的站点地图,那应该不是问题。

代码中的另一个问题是您将站点地图内容作为字符串传递,然后使用平台默认编码转换该字符串。只要您的平台默认编码与您从服务器检索的实际字节匹配(假设您还使用平台默认编码创建了字符串),这将起作用。如果没有,您可能会收到转换错误。

于 2012-12-20T18:50:23.973 回答
0

我在您的代码中看不到任何错误,所以我认为问题出在源头上。您确定源文件包含此元素吗?

也许您可以尝试使用此代码来解析文档中的字符串

builder.parse(new InputSource(new StringReader(xml)));
于 2012-12-20T18:24:15.643 回答