有如下的一个XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<Students>
	<Student id="001" grade="C">
		<Age>16</Age>
		<Name>phoebe</Name>
		<Address>
			<Country>USA</Country>
			<City>Alaska</City>
		</Address>
	</Student>
	<Student id="002" grade="A">
		<Age>18</Age>
		<Name>eileen</Name>
		<Address>
			<Country>USA</Country>
			<City>Chicago</City>
		</Address>
	</Student>
	<Student id="003" grade="C">
		<Age>15</Age>
		<Name>angela</Name>
		<Address>
			<Country>USA</Country>
			<City>Boston</City>
		</Address>
	</Student>
	<Student id="004" grade="B">
		<Age>17</Age>
		<Name>mars</Name>
		<Address>
			<Country>CHN</Country>
			<City>BeiJing</City>
		</Address>
	</Student>
	<Student id="005" grade="C">
		<Age>19</Age>
		<Name>grace</Name>
		<Address>
			<Country>UK</Country>
			<City>London</City>
		</Address>
	</Student>
</Students>

需要从此文件中找出gradeCStudent,并输出其ID和详细信息。使用/Students/Student[@grade=\"C\"]即可选择出满足条件的Student

List<Element> students = root.selectNodes("/Students/Student[@grade=\"C\"]");
if(!students.isEmpty()){
	for(Element student : students){
		System.out.println(student.attributeValue("id"));
	}
}

然后需要从选中的Student中再次获取其子节点,一开始我使用//Name来选取姓名,使用selectSingleNode("//Name")获得的结果都是第一个,再用selectNodes("//Name")选取,看到的结果是选取了所有的Student的Name,正确的方式应该是使用selectSingleNode(".//Name")或直接取Name:selectSingleNode("Name")

完整的代码如下:

import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

public class XPathXmlTest {

	public static void main(String[] args) {
		try {
			SAXReader reader = new SAXReader();
			Document document = reader.read(XPathXmlTest.class.getResourceAsStream("/Students.xml"));
			Element root = document.getRootElement();
			List<Element> students = root.selectNodes("/Students/Student[@grade=\"C\"]");
			if(!students.isEmpty()){
				Node name = null;
				Node age = null;
				Node country = null;
				Node city = null;
				String format = "%s\t%s\t%s\t%s,%s";
				System.out.println(String.format(format, "ID", "Name", "Age", "City", "Country"));
				for(Element student : students){
					name = student.selectSingleNode("Name");
					age = student.selectSingleNode("Age");
					country = student.selectSingleNode("Address/Country");
					city = student.selectSingleNode("Address/City");
					System.out.println(String.format(format, student.attributeValue("id"), name.getText(), age.getText(), city.getText(), country.getText()));
				}
			}
		} catch (DocumentException e) {
			e.printStackTrace();
		}
	}
}
  • 程序输出:
ID Name Age City,Country
001 phoebe 16 Alaska,USA
003 angela 15 Boston,USA
005 grace 19 London,UK
注:需要依赖dom4j和’jaxen’
参考资料
路径表达式 说明
nodename 选取此节点的所有子节点
/ 从根节点选取
// 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置
. 选取当前节点
.. 选取当前节点的父节点
@ 选取属性