XML建模
一.定义:
将XML配置文件中的元素 属性 文本信息 转换成对象的过程叫做XML建模.
二.XML建模
1)根据XML配置文件元素节点创建文件元素节点实体类
2)利用dmo4j+xpath技术实现建模
三.案例演示
1)准备一个xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE config[
<!ELEMENT config (action*)>
<!ELEMENT action (forward*)>
<!ELEMENT forward EMPTY>
<!ATTLIST action
path CDATA #REQUIRED
type CDATA #REQUIRED
>
<!ATTLIST forward
name CDATA #REQUIRED
path CDATA #REQUIRED
redirect (true|false) "false"
>
]>
<!--
config标签:可以包含0~N个action标签
-->
<config>
<!--
action标签:可以饱含0~N个forward标签
path:以/开头的字符串,并且值必须唯一 非空
type:字符串,非空
-->
<action path="/regAction" type="test.RegAction">
<!--
forward标签:没有子标签;
name:字符串,同一action标签下的forward标签name值不能相同 ;
path:以/开头的字符串
redirect:只能是false|true,允许空,默认值为false
-->
<forward name="failed" path="/reg.jsp" redirect="false" />
<forward name="success" path="/login.jsp" redirect="true" />
</action>
<action path="/loginAction" type="test.LoginAction">
<forward name="failed" path="/login.jsp" redirect="false" />
<forward name="success" path="/main.jsp" redirect="true" />
</action>
</config>
2)根据XML文件节点情况,即DTD约束,来定义节点对象模型
在这里依据XML配置文件我们需要三个实体类对象,如下:
注意:对象请由里向外建
ForwardModel
package com.zking.xmlmodel.entity;
import java.io.Serializable;
public class ForwardMode implements Serializable {
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 getRedirect() {
return redirect;
}
public void setRedirect(Boolean redirect) {
this.redirect = redirect;
}
public ForwardMode() {
}
}
ActionModel
package com.zking.xmlmodel.entity;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
public class ActionModel implements Serializable {
private String path;
private String type;
private Map<String, ForwardMode> forwardModel=new HashMap<>();
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;
}
//添加
public void push(ForwardMode fm) {
forwardModel.put(fm.getName(), fm);
}
//取值
public ForwardMode get(String name) {
return forwardModel.get(name);
}
}
ConfigModel
package com.zking.xmlmodel.entity;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
public class ConfigModel implements Serializable {
private Map<String, ActionModel> actionModel=new HashMap<>();
//存
public void push(ActionModel ac) {
actionModel.put(ac.getPath(), ac);
}
//取
public ActionModel get(String path) {
return actionModel.get(path);
}
}
3)以上实体类示例,使用Map集合存放子节点,并利用工厂模式+dom4j+xpath解析XML文件
因为Map集合最大的特点是以键值对的形式存储数据,键唯一值不唯一,键用于存子节点唯一的属性,该属性可以代表整个子节点,值存整个子节点对象.
三.建模开始,代码演示:
package com.zking.xmlmodel.action;
import java.io.InputStream;
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 com.zking.xmlmodel.entity.ActionModel;
import com.zking.xmlmodel.entity.ConfigModel;
import com.zking.xmlmodel.entity.ForwardMode;
public class ConfigModelFactory {
//定义一个默认的xml文件路径
private static final String DEFAULT_PATH = "/config.xml";
//私有化构造函数
private ConfigModelFactory() {
}
//使用自定的文件路径
public static ConfigModel createConfigModel(String path) {
//以流的形式获取xml配置文件
InputStream is = ConfigModelFactory.class.getResourceAsStream(path);
// 创建对象 分别对应xml配置文件中的三个节点
ConfigModel configModel = new ConfigModel();
ActionModel actionModel =new ActionModel();
ForwardMode forwardModel = new ForwardMode();
// 定义属性 分别对应节点的属性
//ActionModel的属性
String actionPath = null;
String actionType = null;
//ForwardModel的属性
String forwardName = null;
String forwardPath = null;
String forwardRedirect = null;
try {
//SAXReader==>Simple API for XML Reader 一种以流的形式解析xml文件的接口
SAXReader saxReader = new SAXReader();
//加载或读取xml文件输入流
Document doc = saxReader.read(is);
// 语法 / 代表定位路径 @ 代表获取属性 当前路径代表找到config节点下的子节点action下的所有子节点
List<Node> actionNodes = doc.selectNodes("/config/action");
//遍历所有的子节点
for (Node actionNode : actionNodes) {
//将子节点强转为元素
Element actionElem = (Element) actionNode;
//找到该元素对应的属性
actionPath = actionElem.attributeValue("path");
actionType = actionElem.attributeValue("type");
//给该子节点对应的实体类添加数据
actionModel.setPath(actionPath);
actionModel.setType(actionType);
//将actionModel对象添加到configModel actionModel是configModel的子节点
configModel.push(actionModel);
//根据当前子节点找到下一个子节点 当前是有多个子节点
List<Node> forwardNodes = actionElem.selectNodes("forward");
//遍历所有的子节点
for (Node forwardNode : forwardNodes) {
//强转
Element forwardElem = (Element) forwardNode;
//获取该子节点的属性值
forwardName = forwardElem.attributeValue("name");
forwardPath = forwardElem.attributeValue("path");
forwardRedirect = forwardElem.attributeValue("redirect");
//将子节点值存到对应的实体类中
forwardModel.setName(forwardName);
forwardModel.setPath(forwardPath);
forwardModel.setRedirect(Boolean.parseBoolean(forwardRedirect));
//将forwardModel对象存到actionModel中 forwardModel是actionModel的子节点
actionModel.push(forwardModel);
}
}
} catch (DocumentException e) {
e.printStackTrace();
}
return configModel;
}
// 使用默认的文件路径
public static ConfigModel createConfigMode() {
return createConfigModel(DEFAULT_PATH);
}
public static void main(String[] args) {
//实例化
ConfigModel cm = ConfigModelFactory.createConfigMode();
//通过获取节点的唯一属性 来获取整个对象
ActionModel actionModel = cm.get("/regAction");
//输出结果
System.out.println("actionPath="+actionModel.getPath()+",actionType="+actionModel.getType());
//通过actionModel来获取forwardModel找到其唯一属性 获取整个对象
ForwardMode forwardMode = actionModel.get("success");
//输出结果
System.out.println("forwardName="+forwardMode.getName()+",forwarPath="+forwardMode.getPath()+",forwardRedirect="+forwardMode.getRedirect());
/**
* 打印的结果如下:
* actionPath=/loginAction,actionType=test.LoginAction
forwardName=success,forwarPath=/main.jsp,forwardRedirect=true
*/
}
}