如果要定位某个 XML 文档中的一段特定信息,那么,通过遍历 DOM 树的众多结点来进行查找显得有些麻烦。 XPath 语言使得访问树结点变得很容易。例如,假设有如下 XML 文档 :
<configuration>
…
<database>
<username>dbuser</username>
<password>secret</password>
…
</database>
</configuration>
你可以通过对 XPath 表达式 /configuration/database/username 求值来得到 database 中的 username 的值。
基本的 XPath 语法类似于在一个文件系统中定位文件 , 如果路径以斜线 / 开始 , 那么该路径就表示到一个元素的绝对路径。 如果路径以双斜线 // 开头 , 则表示选择文档中所有满足双斜线 // 之后规则的元素 ( 无论层级关系 )
JDK5.0 增加了一个 API 计算 XPath 表达式。需要先从 XPathFactory 创建一个 XPath 对象:
XPathFactory xpfactory = XPathFactory.newInstance();
path = xpfactory.newXPath();
然后,调用 evaluate 方法来计算 XPath 表达式:
String username = path.evaluate(“/configuration/database/username”,doc);
e.g:
如果要产生一组结点:
NodeList nodes = (NodeList)path.evaluate(“/gridbag/row”,doc,XPathConstants.NODESET);
若是一个结点:
Node node = (Node)path.evaluate(“/gridbag/row[1]”,doc,XPathConstants.NODE);
若是一个数字:
Int count = ((Number)path.evaluate(“count(/gridbag/row)”,doc,XPathConstants.NUMBER)).intValue();
API javax.xml.xpath.XPathFactory
返回 XPathFactory 实例来创建 XPath 对象
static XPathFactory newInstance()
构建 XPath 对象来计算 XPath 表达式
XPath newXPath()
API javax.xml.xpath.XPathFactory
从给定的起点计算表达式。起点可以是一个结点或结点列表。如果结果是一个结点或结点集,则返回的字符串包含所有文本结点子元素的数据。
String evaluate(String expression, Object startingPoint)
从给定的起点计算表达式。起点可以是一个结点或结点列表。 resultType 是 XPathConstants 类的常量 STRING 、 NODE 、 NODESET 、 NUMBER 或 BOOLEAN 之一。返回值是 String 、 Node 、 NodeList 、 Number 或 Boolean 。
1. 属性的值可以被用来作为选择的准则 , normalize-space 函数删除了前部和尾部的空格 , 并且把连续的空格串替换为一个单一的空格。
选择含有属性id 且其值为'b1' 的BBB 元素: //BBB[@id='b1']
<AAA>
<BBB id = "b1"/>
<BBB name = " bbb "/>
<BBB name = "bbb"/>
</AAA>
选择含有属性 name 且其值 ( 在用 normalize-space 函数去掉前后空格后 ) 为 'bbb' 的 BBB 元素: //BBB[normalize-space(@name)='bbb']
<AAA>
<BBB id = "b1"/>
<BBB name = " bbb "/>
<BBB name = "bbb"/>
</AAA>
2. count() 函数可以计数所选元素的个数
选择含有2 个BBB 子元素的元素 //*[count(BBB)=2]
<AAA>
<CCC>
<BBB/>
<BBB/>
<BBB/>
</CCC>
<DDD>
<BBB/>
<BBB/>
</DDD>
<EEE>
<CCC/>
<DDD/>
</EEE>
</AAA>
选择含有2 个子元素的元素 //*[count(*)=2]
<AAA>
<CCC>
<BBB/>
<BBB/>
<BBB/>
</CCC>
<DDD>
<BBB/>
<BBB/>
</DDD>
<EEE>
<CCC/>
<DDD/>
</EEE>
</AAA>
3. name() 函数返回元素的名称, start-with() 函数在该函数的第一个参数字符串是以第二个参数字符开始的情况返回 true, contains() 函数当其第一个字符串参数包含有第二个字符串参数时返回 true.
选择所有名称为 BBB 的元素 ( 这里等价于 //BBB): //*[name()='BBB']
< AAA >
< BCC >
<BBB />
<BBB />
<BBB />
</ BCC >
< DDB >
<BBB />
<BBB />
</ DDB >
< BEC >
< CCC />
< DBD />
</ BEC >
</ AAA >
选择所有名称以"B" 起始的元素: //*[starts-with(name(),'B')]
< AAA >
<BCC>
<BBB />
<BBB />
<BBB />
</BCC>
< DDB >
<BBB />
<BBB />
</ DDB >
<BEC>
< CCC />
< DBD />
</BEC>
</ AAA >
选择所有名称包含"C" 的元素: //*[contains(name(),'C')]
< AAA >
<BCC>
< BBB />
< BBB />
< BBB />
</BCC>
< DDB >
< BBB />
< BBB />
</ DDB >
<BEC>
<CCC />
< DBD />
</BEC>
</ AAA >