一、前言
1.什么是xml建模
XML建模是指使用XML(可扩展标记语言)来描述事物的结构和属性,用于数据存储、交换和共享。XML建模通常用于创建数据模型,包括具体场景中的数据结构以及数据之间的关系和属性。XML建模的好处是数据可以被跨平台、跨应用程序地传输和重用。
⚠:什么是创建数据模型?
建模是指将XML文档中的数据抽象成一个对象模型(实体对象)或数据模型,以便在程序中以更方便的方式进行处理、分析、展示或者验证。也就是利用Java的特点“万事万物”皆为对象,用操作对象的形式操作xml。
2.为什么要用xml建模
1.类型强制。
XML Schema等模式定义语言可以定义元素及其内容的类型、属性类型、约束条件等,使程序能对XML数据进行更加严格的类型检查,减少了数据解析的错误和风险。
2.数据约束。
XML Schema可以约束XML文档的复杂度、元素、属性等,可以避免文档中可能存在的错误和不合法数据,使应用程序更容易检查数据的完整性和正确性。
小贴士:例如我们在xml中对<action>标签进行dtd约束,将该标签属性进行唯一约束的时候,而这个属性是路径是以“/”开头,不能进行唯一约束只能通过文本约束,这时候我们就可以对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> <action path="/registerAction" type="test.action.RegisterAction"> <forward name="success" path="/index.jsp" redirect="true" /> <forward name="failed" path="/register.jsp" redirect="false" /> </action> <action path="/loginAction" type="test.action.LoginAction"> <forward name="a" path="/index.jsp" redirect="false" /> <forward name="b" path="/welcome.jsp" redirect="true" /> </action> </config>
3.易于理解。
XML建模本身就是一种文本格式,易于阅读和理解,程序员可以通过简单的查看模式文件或代码就能够了解文档中的结构和数据。
4.易于维护。
XML建模工具通常提供了一些可以自动校验、转换、分析和处理XML文件的功能。这些工具使得因为文档结构的变更而导致的代码调整更为容易。
二、xml建模的使用
1.对xml文件进行建模
我们可以把<config>标签看成一个对象ConfigModel(实体类),它下面有<action>标签,而<action>标签有存在多个的关系并且是唯一的(通过path属性区分),所有我们就用map集合进行保存。这个map集合就是对象ConfigModel(实体类)的属性,接着我们肯定要往<config>标签内添加<action>标签这个动作就是添加的方法,有添加肯定有查询,因为<action>标签中的path是唯一的,所有我们就通过path找到指定的<action>标签。
话不多说看代码
package XW.J2EE.XML03; import java.util.HashMap; import java.util.Map; /**config标签实体对象 * @author 索隆 * */ public class ConfigModel { private Map<String, ActionModel> ConfigMap=new HashMap<String, ActionModel>(); public ConfigModel() { // TODO Auto-generated constructor stub } //将ActionModel放入ConfigModel属性中 public void push(ActionModel a) { ConfigMap.put(a.getPath(), a); } //根据ActionModel的path属性查找指定ConfigMap public ActionModel pop(String path) { return ConfigMap.get(path); } @Override public String toString() { return "ConfigModel [ConfigMap=" + ConfigMap + "]"; } }
这里解释下map里面的的键与值,键就是刚刚所提到的path是唯一的,所以这里的键就是<action>标签的path值,而值就是<action>标签的“建模”--ActionModel(实体类)。
那么我们分析一下<action>标签的“建模”--ActionModel(实体类)和刚刚的思维一样,但是<action>标签自己有属性,那么它的属性也是实体中的属性,接着它的下面又是<forward>标签,同样存在多个并且唯一,所以我们也用map集合来保存。由此我们知道该实体有三个属性,path、type、map集合(保存forward实体)。同样也有添加和查询的方法。
package XW.J2EE.XML03; import java.util.HashMap; import java.util.Map; /**action标签实体对象 * @author 索隆 * */ public class ActionModel { private String path; private String type; private Map<String, ForwardModel> ActionMap = new HashMap<>(); public ActionModel() { // TODO Auto-generated constructor stub } 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; } // 将ForwardModel传入ActionModle属性 public void push(ForwardModel f) { ActionMap.put(f.getName(), f); } public Map<String, ForwardModel> getActionMap() { return ActionMap; } public void setActionMap(Map<String, ForwardModel> actionMap) { ActionMap = actionMap; } // 根据ForwardModel的name属性找到指定的ActionMap public ForwardModel pop(String name) { return ActionMap.get(name); } @Override public String toString() { return "ActionModel [path=" + path + ", type=" + type + ", ActionMap=" + ActionMap + "]"; } }
同理<forward>标签也是如此,看到这里我相信你已经大概了解什么是建模了,那我们直接上代码
package XW.J2EE.XML03; /** * Forward标签对象实体 * * @author 索隆 * */ public class ForwardModel { private String name; private String path; private boolean redirect; public ForwardModel() { // TODO Auto-generated constructor stub } 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; } @Override public String toString() { return "ForwardModel [name=" + name + ", path=" + path + ", redirect=" + redirect + "]"; } }
由此我们建模就结束了。
建模结束了,那么我们就要对这些实体进行初始化数据了。这里我提出一个概念,叫做“工厂模式”,工厂模式是23种设计模式中的一种,它提供了一种创建对象的最佳方式。在工厂模式中,我们不必向客户端暴露创建对象的细节,而是提供一个工厂方法,由它代为完成对象的创建过程。工厂模式将实例化对象的过程与客户端分离,使得客户端无需关注对象的创建过程,只需知道所需要的对象类及其参数即可。我这里就来模拟一下工厂模式。
package XW.J2EE.XML03; import java.io.InputStream; import java.util.List; import java.util.Map; import java.util.Set; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; /** * Config.xml的“工厂”,用于初始化数据 * * @author 索隆 * */ public class ConfigFactory { /**初始化数据 * @param xmlPath 需要解析的xml * @return ConfigModel 实体 * @throws Exception */ public static ConfigModel build(String xmlPath) throws Exception { //定义ConfigModel对象 ConfigModel cm = null; // 获取配置文件并转换成流对象 InputStream is = ConfigFactory.class.getResourceAsStream(xmlPath); // 利用dom4j解析流 SAXReader sa = new SAXReader(); // 读取流对象 Document read = sa.read(is); // 获取config标签下的所有action标签 List<Element> configNodes = read.selectNodes("/config/action"); // 遍历所有action标签 for (Element configNode : configNodes) { // 实例化ActionModel对象 ActionModel am = new ActionModel(); // 将解析后的内容添加到ActionModel实体 am.setPath(configNode.attributeValue("path")); am.setType(configNode.attributeValue("type")); // 获取action标签下的所有forward标签 List<Element> forwardNodes = configNode.selectNodes("forward"); for (Element element : forwardNodes) { // 实例化ForwardModle对象 ForwardModel fm = new ForwardModel(); // 将解析后的内容添加到ForwardModle实体 fm.setName(element.attributeValue("name")); fm.setPath(element.attributeValue("path")); fm.setRedirect(!"false".equals(element.attributeValue("redirect"))); am.push(fm); } // 实例化ConfigModel对象 cm = new ConfigModel(); cm.push(am); } return cm; } }
然后我们就可以对工厂初始化的数据进行操作。
public static void main(String[] args) throws Exception { ConfigModel build = ConfigFactory.build("config.xml"); System.out.println("--------------获取第一个action节点并获取type值--------------"); ActionModel pop1 = build.pop("/loginAction"); System.out.println(pop1.getType()); System.out.println("--------------获取第二个action下第二个forword并获取path值--------------"); ActionModel pop2 = build.pop("/loginAction"); ForwardModel ForwardModel = pop2.pop("success"); System.out.println(ForwardModel.getPath()); System.out.println("--------------获取第二个action下的所有forword并获取path值--------------"); Map<String, ForwardModel> actionMap = pop2.getActionMap(); //获取全部的key Set keySet = actionMap.keySet(); for (Object object : keySet) { System.out.println(actionMap.get(object).getPath()); } }