直接求值& Z4 t$ F9 w- a. Y# `
如不美观 XPath 表达式只使用一次,可以跳过编译轨范直接对XPath 对象挪用 evaluate() 体例。可是,如不美观统一个表达式要一再使用多次,编译可能更快一些。/ B7 l# K+ b5 {7 H7 u
最后,计较 XPath 表达式获得结不美观。表达式是针对特定的上下文节点计较的,在这个例子中是整个文档。还必需指定返回类型。这里要求返回一个节点集: l1 m# [5 ~% k2 G' {3 U) {
) @0 o e+ b8 u$ _- k' U- ^; Y4 y
Object result = expr.evaluate(doc, XPathConstants.NODESET); 可以将结不美观强制转化成 DOM NodeList,然后遍历列表获得所有的问题:
( e7 L9 S. S# s4 ?* d. |' ~9 J
% K* s8 O9 m9 V# i# g# o3 ~6 wNodeList nodes = (NodeList) result; for (int i = 0; i < nodes.getLength(); i++) { System.out.println(nodes.item(i).getNodeValue()); } 清单 4 把上述片段组合到了一个轨范中。还要注重,这些体例可能抛出一些搜检异常,这些异常必需在 throws 子句中声明,可是我在膳缦沔把它们袒护起来了:! L' {7 d6 ]4 E1 G+ }
清单 4. 用固定的 XPath 表达式发芽 XML 文档的完整轨范
: |- [: h$ `3 R
& g- o' ]4 t4 G' c' p# Eimport java.io.IOException; import org.w3c.dom.*; import org.xml.sax.SAXException; import javax.xml.parsers.*; import javax.xml.xpath.*; public class XPathExample { public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException, XPathExpressionException { DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); domFactory.setNamespaceAware(true); // never forget this! DocumentBuilder builder = domFactory.newDocumentBuilder(); Document doc = builder.parse("books.xml"); XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); XPathExpression expr = xpath.compile("//book[author='Neal Stephenson']/title/text()"); Object result = expr.evaluate(doc, XPathConstants.NODESET); NodeList nodes = (NodeList) result; for (int i = 0; i < nodes.getLength(); i++) { System.out.println(nodes.item(i).getNodeValue()); } } } XPath 数据模子
- T G; {& H8 {* K& I0 ?$ `每当同化使用诸如 XPath 和 Java 这样两种分歧的说话时,必定会有某些将两者粘合在一路的较着接缝。并非一切都很合拍。XPath 和 Java 说话没有同样的类型系统。XPath 1.0 只有四种根基数据类型:# p% h; Z. y$ L) Y: J/ E8 S- D; C. x
◆ node-set
; r) B( e' W3 Q& F$ U+ C◆ number
$ z: a$ G* Y- E o◆ boolean9 X+ C' G1 t2 s( a3 s
◆ string* m' K( I& G0 R3 b9 o
当然,Java 说话有更多的数据类型,搜罗用户界说的对象类型。
2 I9 Q. u) D- s2 h, Q大都 XPath 表达式,出格是位置路径,都返回节点集。可是还有其他可能。好比,XPath 表达式 count(//book) 返回文档中的图书数目。XPath 表达式 count(//book[@author="Neal Stephenson"]) > 10 返回一个布尔值:如不美观文档中 Neal Stephenson 的著作跨越 10 本则返回 true,否则返回 false。
0 K8 L6 {0 ~7 K: X0 j- Z9 devaluate() 体例被声明为返回 Object。现实返回什么依靠于 XPath 表达式的结不美观以及要求的类型。一般来说,XPath 的9 E5 |' M5 u. {1 h5 ]+ o* V
◆ number 映射为 java.lang.Double
# Y! \# ?# a, e4 t4 ^, z( b◆ string 映射为 java.lang.String9 ]1 q1 V3 V4 Q I
◆ boolean 映射为 java.lang.Boolean
' P) B( b( |0 I% v6 [◆ node-set 映射为 org.w3c.dom.NodeList
& b6 D1 h/ D) C/ G. ^+ d. h# a4 ]XPath 24 |$ H& D2 K+ l/ u* H) ]- k
前面一向假设您使用的是 XPath 1.0。XPath 2 大大扩展和改削了类型系统。Java XPath API 撑持 XPath 2 所需的首要改削是为返回 XPath 2 新数据类型增添常量。! g% ^0 x/ q. B1 O( I q4 v( [
在 Java 入彀较 XPath 表达式时,第二个参数指定需要的返回类型。有五种可能,都在 javax.xml.xpath.XPathConstants 类中命名了常量:- J3 P* P, B7 h" g5 J" M4 _
$ |8 l" E, Y* s/ d% M' r5 u% VXPathConstants.NODESETXPathConstants.BOOLEANXPathConstants.NUMBERXPathConstants.STRINGXPathConstants.NODE最后一个 XPathConstants.NODE 现实膳缦慊有匹配的 XPath 类型。只有知道 XPath 表达式只返回一个节点或者只需要一个节点时才使用它。如不美观 XPath 表达式返回了多个节得而且指定了 XPathConstants.NODE,则 evaluate() 按照文档挨次返回第一个节点。如不美观 XPath 表达式选择了一个空集并指定了 XPathConstants.NODE,则 evaluate() 返回 null。
+ z4 S, b8 c' h+ b* p8 K+ C9 B* P/ I. O) U- E* H$ Y
如不美观不能完成要求的转换,evaluate() 将抛出 XPathException。 |