Java学习之Xml系列七:Dom4j——专题2:基于Xpath的若干复杂例子

关注注释和代码

xml文档:为了说明问题做了一些改动,意思不重要,看代码即可

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- <!DOCTYPE SwordLibrary SYSTEM "SwordTypeDefinition.dtd"> -->
<SwordLibrary>
<Sword sno="s1">
<SwordName>欢欣之刃</SwordName>
<Price>1000</Price>
<Attack factor="1.0">10</Attack>
</Sword>
<Sword sno="s2">
<SwordName>夜叉</SwordName>
<Price>2050</Price>
<Attack factor="2.0">30</Attack>
</Sword>
<Sword sno="s3">
<SwordName>魔棒</SwordName>
<Price type="Dollar">200</Price>
<Attack factor="1.0">0</Attack>
</Sword>
<Sword sno="s5">
<SwordName>大魔棒</SwordName>
<Price type="Dollar">559</Price>
<Attack factor="1.0">
<fire>1</fire>
<ice>2</ice>
</Attack>
</Sword>
<Sword sno="s6">
<SwordName>风杖</SwordName>
<Price type="Dollar">1880</Price>
<Attack factor="1.0">
<fire>3</fire>
<wind>2</wind>
<thunder>0</thunder>
</Attack>
</Sword>

<Sword sno="s9">
<SwordName>圣殿</SwordName>
<Price type="Dollar">575</Price>
<Attack factor="0.0">
<Sword sno="s7">
<SwordName>守护指环</SwordName>
<Price>250</Price>
<Attack factor="0.0">2</Attack>
</Sword>
<Sword sno="s8">
<SwordName>艺人面罩</SwordName>
<Price>325</Price>
<Attack factor="0.0">0.50</Attack>
</Sword>

</Attack>
</Sword>

</SwordLibrary>


java code:

package com.JavaLeaner;

import java.io.File;
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;
import org.junit.Test;

public class XmlDemo7 {

	/*
	 * 对于文本节点条件的最一般例子
	 */
	@Test
	public void Test1() throws DocumentException {
		SAXReader reader = new SAXReader();
		Document doc = reader.read(new File("src/SwordLib.xml"));
		Element root = doc.getRootElement();
		
		Node n=root.selectSingleNode("/SwordLibrary/Sword/SwordName[text()='夜叉']");
		System.out.println(n.getText());

/*		夜叉*/
	}
	
	/*
	 * 对于属性节点条件的最一般例子
	 * 条件可以前置于上层节点
	 */
	@Test
	public void Test2() throws DocumentException
	{
		SAXReader reader = new SAXReader();
		Document doc = reader.read(new File("src/SwordLib.xml"));
		Element root = doc.getRootElement();
		
		Node n=root.selectSingleNode("/SwordLibrary/Sword[@sno='s3']/SwordName");
		System.out.println(n.getText());
		
/*		魔棒*/

	}
	
	/*
	 * SwordLibrary的子元素中包含孙元素SwordName的子元素,即Sword
	 */
	@Test
	public void Test3() throws DocumentException
	{
		SAXReader reader = new SAXReader();
		Document doc = reader.read(new File("src/SwordLib.xml"));
		Element root = doc.getRootElement();
		
		Node n=root.selectSingleNode("/SwordLibrary/*[SwordName]");
		System.out.println(n.getName()); 
		
		/*Sword*/
	}
	
	/*
	 * 本例说明了如何对目标元素的上层元素进行条件限制,即使该条件涉及父元素的其他子孙元素
	 * 在SwordLibrary下有哪个元素含有Attack子元素,且Attack子元素下又有fire孙元素,这个元素的子元素SwordName是什么
	 */
	@Test
	public void Test4() throws DocumentException
	{
		SAXReader reader = new SAXReader();
		Document doc = reader.read(new File("src/SwordLib.xml"));
		Element root = doc.getRootElement();
		
		Node n=root.selectSingleNode("/SwordLibrary/*[Attack/fire]/SwordName");
		System.out.println(n.getText()); 
/*		大魔棒*/
	}
	
	/*
	 * 意在说明如何对名称未定的元素设置文本限制条件
	 * 本例限制条件:Attack元素下任意一个子元素文本值等于3
	 */
	@Test
	public void Test5() throws DocumentException
	{
		SAXReader reader = new SAXReader();
		Document doc = reader.read(new File("src/SwordLib.xml"));
		Element root = doc.getRootElement();
		
		Node n=root.selectSingleNode("/SwordLibrary/*[Attack/*[text()='3']]/SwordName");
		System.out.println(n.getText()); 
		
/*		风杖*/

	}
	
	/*
	 * 绝对路径和相对路径(递归向下)
	 */
	@Test
	public void Test6() throws DocumentException
	{
		SAXReader reader = new SAXReader();
		Document doc = reader.read(new File("src/SwordLib.xml"));
		Element root = doc.getRootElement();
		
		List list1=root.selectNodes("/SwordLibrary/Sword");
		System.out.println(list1.size()); 
		
		List list2=root.selectNodes("/Sword");
		System.out.println(list2.size()); 
		
		List list3=root.selectNodes("//Sword");
		System.out.println(list3.size()); 

/*		
		6
		0
		8
*/
	}
	
	/*
	 * 递归向下也可以用在XPath路径中间,代表中间任意多个元素
	 */
	@Test
	public void Test7() throws DocumentException
	{
		SAXReader reader = new SAXReader();
		Document doc = reader.read(new File("src/SwordLib.xml"));
		Element root = doc.getRootElement();
		
		List<Node> ns=root.selectNodes("/SwordLibrary//SwordName");
		for(int i=0;i<ns.size();i++)
		System.out.println(ns.get(i).getText()); 
		
/*		欢欣之刃
		夜叉
		魔棒
		大魔棒
		风杖
		圣殿
		守护指环
		艺人面罩*/
		
	}
	
	/*
	 * 属性的条件
	 * 条件可以嵌套,即条件中的元素、属性、或者其他函数值也可以添加条件.[[]]
	 */
	@Test
	public void Test8() throws DocumentException
	{
		SAXReader reader = new SAXReader();
		Document doc = reader.read(new File("src/SwordLib.xml"));
		Element root = doc.getRootElement();
		
		List<Node> ns=root.selectNodes("//Sword[Attack[@factor='1.0']]/SwordName");
		for(int i=0;i<ns.size();i++)
		System.out.println(ns.get(i).getText()); 
		
/*		欢欣之刃
		魔棒
		大魔棒
		风杖*/

	}
	
	/*
	 * 条件设置[]的可以凑在一起,分别描述不同的子元素条件或者text()等。[][]
	 */
	@Test
	public void Test9() throws DocumentException
	{
		SAXReader reader = new SAXReader();
		Document doc = reader.read(new File("src/SwordLib.xml"));
		Element root = doc.getRootElement();
		
		List<Node> ns=root.selectNodes("//Sword[Price>0 and Price<1000][Attack[@factor='0.0']]/SwordName");
		for(int i=0;i<ns.size();i++)
		System.out.println(ns.get(i).getText()); 
		
/*		圣殿
		守护指环
		艺人面罩*/

	}
	
	
	/*
	 * []不仅可以设置条件,还可以设置下标,注意从1开始,不是0
	 * last()代表最后的
	 */
	@Test
	public void Test10() throws DocumentException
	{
		SAXReader reader = new SAXReader();
		Document doc = reader.read(new File("src/SwordLib.xml"));
		Element root = doc.getRootElement();
		
		Node n=root.selectSingleNode("//Sword[last()]/Attack/Sword[2]/SwordName");
		System.out.println(n.getText()); 
		
/*		艺人面罩*/


	}
	/*
	 * Sword[1]第一个就是第一个Sword,而不能理解为满足下述条件的第一个
	 */
	@Test
	public void Test11() throws DocumentException
	{
		SAXReader reader = new SAXReader();
		Document doc = reader.read(new File("src/SwordLib.xml"));
		Element root = doc.getRootElement();
		
		List<Node> ns=root.selectNodes("//Sword[1]/Attack/Sword[2]/SwordName");
		for(int i=0;i<ns.size();i++)
		System.out.println(ns.get(i).getText());

/*		无内容*/
	}
	
	/*
	 * 从上下两个例子可以看出,下标使用比较特别。
	 * 第二个变成了从两类相对路径上的两个第二个Sword
	 */
	@Test
	public void Test12() throws DocumentException
	{
		SAXReader reader = new SAXReader();
		Document doc = reader.read(new File("src/SwordLib.xml"));
		Element root = doc.getRootElement();
		
		List<Node> ns=root.selectNodes("//Sword[2]/SwordName");
		for(int i=0;i<ns.size();i++)
		System.out.println(ns.get(i).getText()); 
		
/*		夜叉
		艺人面罩*/

		
	}
	
	
	/*
	 * ../代表从父节点开始
	 * 注意:父节点是..    不是../
	 * ./是当前路径
	 */
	@Test
	public void Test13() throws DocumentException
	{
		SAXReader reader = new SAXReader();
		Document doc = reader.read(new File("src/SwordLib.xml"));
		Element root = doc.getRootElement();
		
		Element ename=(Element)root.selectSingleNode("//Sword[3]/SwordName");
		System.out.println(ename.getName()+":"+ename.getText()); 
		
		Element eprice=(Element)ename.selectSingleNode("../Price");
		System.out.println(eprice.getName()+":"+eprice.getText()); 
		
		Element esword=(Element)ename.selectSingleNode("..");
		System.out.println(esword.getName()); 
		
		Element eAttack=(Element)esword.selectSingleNode("./Attack");//"/Attack"不可以
		System.out.println(eAttack.getName()+":"+eAttack.getText()); 

/*		SwordName:魔棒
		Price:200
		Sword
		Attack:0
		*/
		
	}
	
	
	/*
	 * 下表需要出现在比较条件中时,用position()
	 */
	@Test
	public void Test14() throws DocumentException
	{
		SAXReader reader = new SAXReader();
		Document doc = reader.read(new File("src/SwordLib.xml"));
		Element root = doc.getRootElement();
		
		List<Node> ns=root.selectNodes("//Sword[position()<=2]/SwordName");
		for(int i=0;i<ns.size();i++)
		System.out.println(ns.get(i).getText()); 
		

/*		欢欣之刃
		夜叉
		守护指环
		艺人面罩*/
		
	}
	
	/*
	 * 字符串处理函数,注意标号都是从1开始
	 */
	@Test
	public void Test15() throws DocumentException
	{
		SAXReader reader = new SAXReader();
		Document doc = reader.read(new File("src/SwordLib.xml"));
		Element root = doc.getRootElement();
		
		System.out.println("1:"); 
		List<Node> ns=root.selectNodes("//Sword/SwordName[contains(text(),'魔')]");
		for(int i=0;i<ns.size();i++)
		System.out.println(ns.get(i).getText()); 
		
		System.out.println("2:"); 
		List<Node> ns2=root.selectNodes("//Sword[contains(SwordName,'魔')]/SwordName");
		for(int i=0;i<ns2.size();i++)
		System.out.println(ns2.get(i).getText()); 

		System.out.println("3:"); 
		List<Node> ns3=root.selectNodes("//Sword/SwordName[starts-with(text(),'魔') and ends-with(text(),'棒')]");
		for(int i=0;i<ns3.size();i++)
		System.out.println(ns3.get(i).getText()); 
		
		System.out.println("4:"); //substring从1开始不是从0开始,一定注意!sno='s2'
		List<Element> ns4=root.selectNodes("//Sword[substring(@sno,2,1)='2']/SwordName");
		for(int i=0;i<ns4.size();i++)
		System.out.println(ns4.get(i).getText()); 
		
/*			1:
			魔棒
			大魔棒
			2:
			魔棒
			大魔棒
			3:
			魔棒
			4:
			夜叉		*/
	}
		
	
}


转载于:https://my.oschina.net/happyBKs/blog/306983

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值