dom4j+xpath解析xml文件

3 篇文章 0 订阅

1.XML建模 

注意标红的字体

1.要先懂得DOM由节点组成

       Node

         元素节点

         属性节点

         文本节点

解析所需要的jar包:https://mvnrepository.com/search?q=dom4j 以及 https://mvnrepository.com/search?q=jaxen (所有的jar包都可以在那里下载,那是一个公认的仓库)

1.2 创建.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE config>
<config>
<action type="btest" path="/clogin.jsp">
<forward path="/alogin.jsp" redirect="false" name="afailed"/>
<forward path="/areader.jsp" redirect="true" name="asucees"/>
</action>
<action type="atest" path="/dlogin.jsp">
<forward path="/blogd.jsp" redirect="false" name="bfailed"/>
<forward path="/breader.jsp" redirect="true" name="bsucees"/>
</action>
</config>

1.3 创建.xml文件每个节点对应的Bean(实体类)

1.从底层的元素子节点开始创建实体类,从内到外的搭建,思路不会乱,环环相扣  --重点

可以利用List集合或Map几个储存数据

2.利用工厂模式和单例模式的特点,使XML文件中加载一次

从上面的.xml文件可以分析出,主要由三个节点构成,分别是forward、action、config组成,创建对应的Bean

1.3.1 创建forward实体类

package com.entity;
/**
 * Stdudent.xml中的forward节点实体类
 */
import java.io.Serializable;

public class ForwardNode implements Serializable{

	private static final long serialVersionUID = 1L;
	
	public ForwardNode() {
		super();
	}
	private String name;
	private String path;
	private boolean redirect;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPath() {
		return path;
	}
	public void setPath(String path) {
		this.path = path;
	}
	public boolean isRedirect() {
		return redirect;
	}
	public void setRedirect(boolean redirect) {
		this.redirect = redirect;
	}
	public void setRedirect(String redirect) {
		this.redirect = Boolean.getBoolean(redirect);
	}
	
	@Override
	public String toString() {
		return "Forward [name=" + name + ", path=" + path + ", redirect=" + redirect + "]";
	}
	
	

}

1.3.2 创建对应的Action实体类

package com.entity;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * 实例化Student.xml中的action节点
 */
public class ActionNode implements Serializable{

	private static final long serialVersionUID = 1L;
	
	private String path;
	private String type;
	private Map<String, ForwardNode> forwardMaps = new HashMap<String, ForwardNode>();
	
	//用户验证XMl格式是否正确
	/**
	 * forwardNode.getName()验证name是否存在
	 * @param forward
	 */
	public void putforwardMaps(ForwardNode forwardNode) {
		//如果name已存在
		if(forwardMaps.containsKey(forwardNode.getName())) {
			//抛出异常,提示name已存在
			throw new RuntimeException(""+forwardNode.getName()+"该name以存在");
		}
		//将forwardNode存放于Map(forwardMaps)集合中
		forwardMaps.put(forwardNode.getName(), forwardNode);
	}
	/**
	 * 通过键(name)查询Map值
	 * @param name
	 * @return
	 */
	public ForwardNode getforwardMaps(String name) {
		//返回对象
		return forwardMaps.get(name);
	}
	
	
	public ActionNode() {
		super();
	}
	public String getPath() {
		return path;
	}
	public void setPath(String path) {
		this.path = path;
	}
	public String getType() {
		return type;
	}
	public void setType(String type) {
		this.type = type;
	}
	@Override
	public String toString() {
		return "Action [path=" + path + ", type=" + type + "]";
	}
}

1.3.3 创建config对应的实体类

package com.entity;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * Student.xml中的config节点的实体类
 */
public class ConfigNode implements Serializable{

	private static final long serialVersionUID = 1L;
	//得到action节点就=得到了下面的全部子节点
	private Map<String, ActionNode> actionMaps = new HashMap<String,ActionNode>();
	
	//无参构造方法
	public ConfigNode(){
		
	}
	//验证格式是否正确--如果在实例化的时候验证的话要声明很多个。。如果在实体类中进行的话可以节省代码
	public void putactionMaps(ActionNode actionNode) {
		String redex = "^/.+$";  //写正则用于判断第一个是否是/
		Pattern pattern = Pattern.compile(redex); //编辑正则
		Matcher matcher = pattern.matcher(actionNode.getPath());  //使用编译后的正则匹配actionNode中的路径
		boolean bool = matcher.find();  //匹配成功为true,失败为false
		if(!bool) {   //如果失败
			//如果不是以/开头的,抛出异常,程序终止
			throw new RuntimeException("path["+actionNode.getPath()+"]中必须以/开头"); 
			//如果actionMaps中已存在
		}else if(actionMaps.containsKey(actionNode.getPath())) {
			//抛出异常,提示已存在
			throw new RuntimeException(""+actionNode.getPath()+"该路径以存在");
		}
		//将对象添加到Map(actionMaps)集合中
		actionMaps.put(actionNode.getPath(), actionNode);
	}
	//通过键(name)得到actionMaps集合里面的内容
	public ActionNode getactionMaps(String name) {
		//返回对象
		return actionMaps.get(name);
	}
	
	

}

1.4 测试

package com.test;
import java.io.InputStream;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import com.entity.ActionNode;
import com.entity.ConfigNode;
import com.entity.ForwardNode;

public class StudentFactory{// extends HttpServlet

	/*
	 *  单例模式
	 *  1.私有化构造方法
	 *  2.公开一个代理方法
	 */ 
	/*
	 * 提取区
	 */
	private static List<Element> actionElements = null;
	private static ActionNode  actionNode = new ActionNode();
	private static InputStream is = null;
	private static List<Element> configElements = null;
	private static List<Element> forwardElements =  null;
	private static String forwardName = null;
	private static String forwardPath =  null;
	private static String forwardRedirect = null;
	private static String actionPath = null;
	private static String actionType = null;
	
	
	//私有化configNode类
	private static ConfigNode configNode = null;
	
	//私有化构造方法
	private StudentFactory() {
		
	}
	//公开一个代理方法
	public static ConfigNode createconfigNode(String filePath) {  
		//如果configNode为null
		if(configNode == null) {
			//实例化configNode对象
			configNode = new ConfigNode();
			//调用初始化方法
			init(filePath);
		}
		//返回configNode对象
		return configNode;
	}
	//用于初始化的方法
	public static void init(String filePath) {
		try {
		//获得输入流
		is = StudentFactory.class.getResourceAsStream(filePath);
		//实例化SAXReader,读取流,返回文档
		Document document = new SAXReader().read(is);
		//查询文档中config元素节点以下的所有子节点
		configElements = document.selectNodes("config");
			for (Element configElement : configElements) {
				//通过configElement查询其子节点action
				actionElements = configElement.selectNodes("action");
				for (Element actionElement : actionElements) {
					//获得actionElement元素节点中的属性path的文本元素
					actionPath = actionElement.attribute("path").getText();
					actionType = actionElement.attribute("type").getText();
					//将得到的path文本元素添加到actionNode实体类中
					actionNode.setPath(actionPath);
					actionNode.setType(actionType);
					//将得到的对象添加到configNode之中
					configNode.putactionMaps(actionNode);
					//通过actionElement节点查询forward子节点的内容
					forwardElements = actionElement.selectNodes("forward");
					for (Element forwardElement : forwardElements) {
						forwardName = forwardElement.attributeValue("name");
						forwardPath = forwardElement.attributeValue("path");
						forwardRedirect = forwardElement.attributeValue("redirect");
						ForwardNode forwardNode = new ForwardNode();
						forwardNode.setName(forwardName);
						forwardNode.setPath(forwardPath);
						forwardNode.setRedirect(forwardRedirect);
						actionNode.putforwardMaps(forwardNode);
					}
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
 	public static void main(String[] args) {
 		new StudentFactory().createconfigNode("Student.xml");
 		//通过键path查询值
 		//System.out.println(configNode.getactionMaps("/dlogin.jsp"));  
 		//通过键name查询值
 		//System.out.println(actionNode.getforwardMaps("bfailed"));
 		
	}
}

 

希望能帮助到你,如有改进或者代码错误可以添加QQ细谈:304808680

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值