java xpath使用_在XPath中使用Java语言NamespaceContext对象

先决条件和示例

在本文中,我假设您熟悉Brett McLaughlin的“从Java™平台评估XPath”中描述的技术细节。 如果你不知道如何使用XPath运行Java程序,请参阅Brett的文章(请参阅相关主题的文章链接。)同样是真实的加载一个XML文件,并评估XPath表达式所需的API 。

所有示例都将使用以下XML文件:

清单1.示例XML
<?xml version="1.0" encoding="UTF-8"?>

<books:booklist
  xmlns:books="http://univNaSpResolver/booklist"
  xmlns="http://univNaSpResolver/book"
  xmlns:fiction="http://univNaSpResolver/fictionbook">
  <science:book xmlns:science="http://univNaSpResolver/sciencebook">
    <title>Learning XPath</title>
    <author>Michael Schmidt</author>
  </science:book>
  <fiction:book>
    <title>Faust I</title>
    <author>Johann Wolfgang von Goethe</author>
  </fiction:book>
  <fiction:book>
    <title>Faust II</title>
    <author>Johann Wolfgang von Goethe</author>
  </fiction:book>
</books:booklist>

这个XML示例在根元素中声明了三个命名空间,在结构中更深的元素中声明了一个命名空间。 您将看到此设置导致的差异。

关于此XML示例的第二件有趣的事情是,元素booklist具有三个子级,均名为book 。 但是第一个子级具有命名空间science ,而第二个子级具有命名空间fiction 。 这意味着这些元素与XPath完全不同。 您将在下面的示例中看到结果。

关于示例源代码的一点说明:该代码不是为维护而优化的,而是为了提高可读性。 这意味着它具有一些冗余。 通过System.out.println()以最简单的方式产生输出。 与输出有关的所有代码行均在本文中缩写为“ ...”。 另外,我不在本文中介绍辅助方法,但它们包含在下载文件中(请参阅下载 )。

理论背景

命名空间的含义是什么,为什么要关心它们? 名称空间是元素或属性的标识符的一部分。 您可以具有具有相同本地名称但具有不同名称空间的元素或属性。 他们是完全不同的。 请参见上面的示例( science:bookfiction:book )。 如果合并来自不同来源的XML文件,则需要命名空间来解决命名冲突。 以一个XSLT文件为例。 它由XSLT命名空间的元素,您自己的命名空间的元素和XHTML命名空间的元素(通常)组成。 使用名称空间,可以避免有关具有相同本地名称的元素的歧义。

名称空间由URI定义(在本示例中为http://univNaSpResolver/booklist )。 为了避免使用此长字符串,请定义与此URI关联的前缀(在示例中为books )。 请记住,前缀就像一个变量:其名称无关紧要。 如果两个前缀引用相同的URI,则带前缀的元素的名称空间将相同(有关此示例,请参见清单5中的示例1)。

XPath表达式使用前缀(例如, books:booklist/science:book ),并且您必须提供与每个前缀关联的URI。 这就是NamespaceContext进入的地方。它正是这样做的。

本文介绍了在前缀和URI之间提供映射的不同方法。

在XML文件中,映射由xmlns属性提供,例如: xmlns:books="http://univNaSpResolver/booklist"xmlns="http://univNaSpResolver/book" (默认名称空间)。

提供名称空间解析的必要性

如果您具有使用名称空间的XML,那么如果不提供NamespaceContext,则XPath表达式将失败。 清单2中的示例0显示了这种情况。 XPath对象是在加载的XML文档上构造和评估的。 首先,尝试写一个表达式没有任何名称空间前缀( result1 )。 在第二部分中,使用名称空间前缀( result2 )编写表达式。

清单2.没有名称空间解析的示例0
private static void example0(Document example)
            throws XPathExpressionException, TransformerException {
        sysout("\n*** Zero example - no namespaces provided ***");

        XPath xPath = XPathFactory.newInstance().newXPath();

...
        NodeList result1 = (NodeList) xPath.evaluate("booklist/book", example,
                XPathConstants.NODESET);
...
        NodeList result2 = (NodeList) xPath.evaluate(
                "books:booklist/science:book", example, XPathConstants.NODESET);
...
    }

这将导致以下输出。

清单3.示例0的输出
*** Zero example - no namespaces provided ***
First try asking without namespace prefix:
--> booklist/book
Result is of length 0
Then try asking with namespace prefix:
--> books:booklist/science:book
Result is of length 0
The expression does not work in both cases.

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值