命名空间声明的 XPath 解析 [英] XPath Parsing of Namespace Declarations

查看:30
本文介绍了命名空间声明的 XPath 解析的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 XPath 提取 URL128 XML 元素的值.即使我在下面的示例中只有一个,也可以有很多.当我在 SearchResponse 元素上包含 xmlns='http://c1.net.corbis.com/' 时,我得到一个空的 NodeList,但是当我删除该命名空间元素时,它工作正常.有没有我遗漏的配置?

I'm using XPath to pull out just the values of URL128 XML element. There can be many of these even though I just have one in the below example. When I include xmlns='http://c1.net.corbis.com/' on the SearchResponse element I get an empty NodeList, but when I remove that namespace element it works fine. Is there a configuration I'm missing?

String xmlData = "<SearchResponse xmlns='http://c1.net.corbis.com/'><searchResultDataXML><SearchResultData><SearchRequestUID Scope='Public' Type='Guid' Value='{cded773c-c4b7-4dd8-aaee-8e5b8b7a2475}'/><StartPosition Scope='Public' Type='Long' Value='1'/><EndPosition Scope='Public' Type='Long' Value='50'/><TotalHits Scope='Public' Type='Long' Value='323636'/></SearchResultData></searchResultDataXML><imagesXML><Images><Image><ImageUID Scope='Public' Type='Guid' Value='{a6f6d3e2-2c3f-4502-9741-eae2e1bb573a}'/><CorbisID Scope='Public' Type='String' Value='42-25763849'/><Title Scope='Public' Type='String' Value='Animals figurines'/><CreditLine Scope='Public' Type='String' Value='© Ocean/Corbis'/><IsRoyaltyFree Scope='Public' Type='Boolean' Value='True'/><AspectRatio Scope='Public' Type='String' Value='0.666667'/><URL128 Scope='Public' Type='String' Value='http://cachens.corbis.com/CorbisImage/thumb/25/76/38/25763849/42-25763849.jpg'/></Image></Images></imagesXML></SearchResponse>";
            InputSource source = new InputSource(new StringReader(xmlData));

            XPath xPath = XPathFactory.newInstance().newXPath();
            NodeList list = null;
            try {
                list = (NodeList) xPath.evaluate("//URL128/@Value", source, XPathConstants.NODESET);
            } catch (Exception ex) {
                System.out.println(ex.getMessage());
            }
            for (int i = 0; i < list.getLength(); i++) {
                System.out.println(list.item(i).getTextContent());
            }

推荐答案

好吧,长话短说,您需要提供一个 NamespaceContext 到您的 XPath:

Well, long story short you need to provide a NamespaceContext to your XPath:

final XPath xPath = XPathFactory.newInstance().newXPath();
xPath.setNamespaceContext(new NamespaceContext() {
    @Override
    public Iterator<String> getPrefixes(final String namespaceURI) {
        return null;
    }
    @Override
    public String getPrefix(final String namespaceURI) {
        return null;
    }
    @Override
    public String getNamespaceURI(final String prefix) {
        return "http://c1.net.corbis.com/";
    }
});
final NodeList list = (NodeList) xPath.evaluate("//c:URL128/@Value", source, XPathConstants.NODESET);
for (int i = 0; i < list.getLength(); i++) {
    System.out.println(list.item(i).getTextContent());
}

在这种情况下,XPath 要求我们实现的唯一方法似乎是 getNamespaceURI(String prefix).

It seems the only method XPath requires us to implement in this case is getNamespaceURI(String prefix).

请注意,在这种情况下,c:URL128"中的实际前缀并不重要——您可以轻松地使用:URL128".当您在 XML 中确实有多个命名空间时,区分它们就变得很重要(使用 Map 或一系列 if-then-else> 如果元素相对较少).

Note that the actual prefix in "c:URL128" doesn't really matter in this case—you could just as easily use ":URL128". When you do have multiple namespaces in your XML then it becomes important to distinguish among them (using a Map or a series of if-then-else if relatively few elements).

如果您不能或不想对前缀进行硬编码,您可以自己从 XML 文档中提取它们,但这需要更多的代码...

If you can't or don't want to hard code the prefixes you can extract them yourself from the XML document but that requires a little more code...

另见这篇博文了解更多详情.

这篇关于命名空间声明的 XPath 解析的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆