目录
什么是xml?
xml的作用:
一,XML元素的定义语法
二,XML属性的定义语法
建模并解析到内存条
今天小编给大分享一下xml配置文件的解析与读取,希望能对各位大佬们有所帮助。
什么是xml?
是标记语言,按照规定好的语法去编写xml文件,可以被解析成功。
xml的作用:
1,数据交互(可跨语言进行数据传递)
2,做配置
学习xml目的:自定义MVC需要手动配置xml。
标准的xml格式是怎么样的呢?
1,只有一个根元素(首位呼应)
2,,xml标签大小写正确区分
3,正确使用嵌套(不能错乱)
4,使用合法的标签名(不能使用关键字)与属性(它有规定好的属性,不能DIY)
需要定义的代码
<persons>
<person pid="p1" sex="男" qq="aaa" parent="p2">
<name>张小明</name>
<age>10</age>
<contact>
<phone>1234567</phone>
</contact>
<br/>
</person>
<person pid="p2">
<name>张大明</name>
<age>35</age>
<contact>
<email>123@qq.com</email>
</contact>
</person>
</persons>
一,XML元素的定义语法
xml加入前最上面先声明:
<!DOCTYPE rott[]>
1,元素的分类语法
//rott 代表根元素
<!ELEMENT element-name Empty> 空元素
<!ELEMENT element-name(#PCDATA)> 文本元素
<!ELEMENT element-name(e1,e2,e3..)> 混合元素
2,次数语法
0或1:?
0~N:*
1~N:+
例
<!DOCTYPE persons[
<!ELEMENT persons (person+)>
<!ELEMENT person (name,age,contact,br*)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ELEMENT contact (phone|email)>
<!ELEMENT br EMPTY>
]>
二,XML属性的定义语法
xml加入前最上面先声明:
<!ATTLIST element-name att_name type desc>
1,属性类型语法
ID(编号)、CDATA(文本内容)、IDREF(父标签)、reference,(男|女)
#REQUIRED:必填 #IMPLIED:选填
‘默认值’:只有type为(男,女)类型时,dese才可使用默认值方式
例
<!ATTLIST person pid ID #REQUIRED sex (男|女) '女' qq CDATA #IMPLIED parent IDREF #IMPLIED >
注意事项:属性定义代码必须在元素定义代码里面,也就是说,元素定义代码必须包含元素定义代码。
读取xml案例
需要使用jar包详解
beanutils 处理java反射机制的包
logging 处理日志文件的包
dom4j 解析xml文件的包
neat 解析xml文件的包
jstl jsp标签库
conector 加载mysql驱动程序的包
standard servert处理请求的包
需要解析读取的students.xml
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student sid="s001">
<name>小明</name>
</student>
<student sid="s002">
<name>小芳</name>
</student>
<student sid='s003'>
<name>小王</name>
</student>
</students>
结果如下
解析代码如下
public static void main(String[] args) throws Exception {
InputStream in = Wordxml2Read.class.getResourceAsStream("/students.xml");//通过Java反射机制获取IO流
SAXReader reader = new SAXReader();//实例化xml解析器
Document doc = reader.read(in);//读取流对象,并用Document封装
Element root = doc.getRootElement();//获取Element根节点
List<Element> students = root.selectNodes("/students/student");//获取根节点下的多个子节点全部属性
for (Element student : students) {//遍历全部子节点
String sid = student.attributeValue("sid");//通过attributeValue()得到子节点属性
System.out.println("sid="+sid);
List<Element> name = student.selectNodes("name");
for (Element names : name) {
System.out.println(names.getText());
}
}
//String name = student.selectSingleNode("name").getText();//获取单个节点
}
}
建模并解析到内存条
需要建模的config.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="/studentAction" type="org.lisen.mvc.action.StudentAction">
<forward name="students" path="/students/studentList.jsp" redirect="false"/>
</action>
<action path="/studentAction01" type="org.lisen.mvc.action.StudentAction">
<forward name="students01" path="/students/studentList.jsp" redirect="true"/>
</action>
</config>
结果如下
configModel类
package mvc;
import java.util.HashMap;
import java.util.Map;
import Exception.ActionDuliplateDefinitionException;
import Exception.ActionNoFindException;
public class ConfigModel {
Map<String,ActionModel> actionMap=new HashMap<String, ActionModel>();
//获取action的path,然后保存到集合中
public void addConfig(ActionModel action) {
if(actionMap.containsKey(action.getPath())) {//如果action的path值已存在,就报异常,因为action的键是唯一的
throw new ActionDuliplateDefinitionException("action path:" + action.getPath()+ " 不能重复");
}
actionMap.put(action.getPath(), action);
}
//获取xml里action的path值
public ActionModel find(String path) {
if(!actionMap.containsKey(path)) {//xml中如果action里面不包含path报异常
throw new ActionNoFindException("action path:"+path+"没有找到");
}
return actionMap.get(path);
}
}
ActionModel类
package mvc;
import java.util.HashMap;
import java.util.Map;
import Exception.ForwardDuliplateDefinitionException;
import Exception.ForwardNotFoundException;
public class ActionModel {
String path;
String type;
Map<String, ForwardMeodel> forwardMap=new HashMap<String, ForwardMeodel>();
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 "ActionModel [path=" + path + ", type=" + type + "]";
}
//获取forward的path,然后保存到集合中
public void addAction(ForwardMeodel forward) {
System.out.println(forward);
if(forwardMap.containsKey(forward.getName())) {//如果forwardMap的name值已存在,就报异常,因为forward的键是唯一的
throw new ForwardDuliplateDefinitionException("forward name:"+forward.getName()+"不能重复");
}
forwardMap.put(forward.getName(), forward);
}
//获取xml里forward的name值
public ForwardMeodel find(String name) {
if(!forwardMap.containsKey(name)) {//xml中如果forward里面不包含name报异常
throw new ForwardNotFoundException("forward name:"+name+"不存在");
}
return forwardMap.get(name);
}
}
ForwardMeodel类
package mvc;
public class ForwardMeodel {
String name;
String path;
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) {
if("true".equals(redirect) || "false".equals(redirect)) {
this.redirect= Boolean.valueOf(redirect);
}else {
throw new RuntimeException("属性redirect的值必须位ture或者false");
}
}
@Override
public String toString() {
return "ForwardMeodel [name=" + name + ", path=" + path + ", redirect=" + redirect + "]";
}
}
解析并生成ConfigModelFactory模型
package mvc;
import java.io.InputStream;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public final class ConfigModelFactory {
private ConfigModelFactory() {}//单例模式(中的饥饿模式,只有一个实例,不能被实例化)
private static ConfigModel config=new ConfigModel();
//静态代码块,在类加载的时候只执行一次,在这里完成config.xml文件的解析和Config相关的
//模型的建立,这样在整个系统运行阶段只会解析一次
static{
try {
InputStream is = ConfigModelFactory.class.getResourceAsStream("/config.xml");//获取IO流对象
SAXReader reader=new SAXReader();//实例化xml解析器
Document doc = reader.read(is);//读取并放入Document文档
Element root=doc.getRootElement();//获取Element根节点
List<Element> Nodes = root.selectNodes("/config/action");//获取全部元素(根元素下)
for (Element action : Nodes) {//遍历子元素
String path = action.attributeValue("path");
String type=action.attributeValue("type");//通过attributeValue()方法得到属性文本
ActionModel actionModel=new ActionModel();
actionModel.setPath(path);//将属性设置到ActionModel中
actionModel.setType(type);
List<Element> forwards = action.selectNodes("forward");//获取全部元素(根元素下)
for (Element f : forwards) {//遍历子元素
String name = f.attributeValue("name");//通过attributeValue()方法得到属性文本
String fpath = f.attributeValue("path");
String redirect = f.attributeValue("redirect");
ForwardMeodel forwardMeodel=new ForwardMeodel();
forwardMeodel.setName(name);//将属性设置到ForwardMeodel中
forwardMeodel.setPath(fpath);
forwardMeodel.setRedirect(redirect);
actionModel.addAction(forwardMeodel);//将forwardMeodel添加到actionModel
}
config.addConfig(actionModel);//将actionModel添加到configMepdel
}
}catch(Exception e){
throw new RuntimeException(e);//接收到的异常信息向上刨
}
}
//获取系统的Config配置对象
public static ConfigModel getConfig() {
return config;
}
//测试代码
public static void main(String[] args) {
ConfigModel configModel = getConfig();
ActionModel action = configModel.find("/studentAction");
System.out.println(action);
ForwardMeodel forward = action.find("students");
System.out.println(forward);
}
}