XML解析,DTD约束,Schema约束,反射

59 篇文章 0 订阅
50 篇文章 0 订阅

XML
XML就是一种数据的描述语言,虽然它是语言,但是通常情况下,它并不具备常见语言的基本功能——被计算机识别并运行。只有依靠另一种语言,来解释它,使它达到你想要的效果或被计算机所接受。

示例⬇

<?xml version="1.0" encoding="UTF-8"?>
<hello version="1.0" id="1">
	<a></a>
	<c>&lt;<!-- 使用转义符代替小于号大于号等等 -->AAAA</c>
	<b>
	<!-- CDATA不会被解析,出现大量的转义符出现在XML文档中时,会大幅降低可读性,
	CDATA段中出现的字符无需使用转义字符替代,为了避免频繁使用转义符可以使用CDATA -->
	<![CDATA[
		if(a>b&&b<c){}
	]]>
	</b>
</hello>

DTD约束
给XML加以约束
DTD约束的引用方法(一般放在XML头下)
1.内部DTD,在XML文档内部嵌入DTD,只对当前XML有效
2.外部DTD-本地DTD,DTD文档在本地系统上,公司内部自己项目使用
3.外部DTD-公共DTD,DTD文档在网络上,一般都有框架提供。
注意:一般使用框架提供的DTD,不需要自己编写,只要能够读懂就足够了
在这里插入图片描述在这里插入图片描述
案例实现
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
DTD文件中属性类型的选项
在这里插入图片描述
DTD约束文件

<?xml version="1.0" encoding="UTF-8"?>
<!--
	模拟serblet2.3规范,如果开发人员需要在xml使用当前DTD约束,必须包括DOCTYPE。
	格式如下:
	<!DOCTYPE web-app SYSTEM "web-app_2_3.dtd">
-->
<!ELEMENT web-app (servlet*,servlet-mapping*,welcome-file-list?)>
<!ELEMENT servlet (servlet-name,description?,(servlet-class|jsp-file))>
<!ELEMENT servlet-mapping (servlet-name,url-pattern+)>
<!-- #PCDATA为只能出现文本 -->
<!ELEMENT servlet-name (#PCDATA)>
<!ELEMENT servlet-class (#PCDATA)>
<!ELEMENT url-pattern (#PCDATA)>
<!ELEMENT description (#PCDATA)>
<!ELEMENT jsp-file (#PCDATA)>

<!ELEMENT welcome-file-list (welcome-file+)>
<!ELEMENT welcome-file (#PCDATA)>

<!ATTLIST web-app version CDATA #IMPLIED>

使用DTD配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app SYSTEM "web-app_2_3.dtd">
<web-app version="1.0">
	<servlet>
		<servlet-name>aynor</servlet-name>
		<servlet-class>xxxxxxxxxx</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>aynor</servlet-name>
		<url-pattern>hello</url-pattern>
	</servlet-mapping>
	<welcome-file-list>
		<welcome-file></welcome-file>
	</welcome-file-list>
</web-app>

Schema约束
比DTD强大的多,是DTD的替代者,支持名称空间
在这里插入图片描述
在这里插入图片描述
XML解析
一共三种解析方式,四种解析开发包
在这里插入图片描述
在这里插入图片描述
使用Dom4j对XML进行解析(需要导入jar包,这里用的是dom4j-1.6.1.jar)

package cn.aynortechnology.xml.dom4j;

import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;

public class TestDom4j {
	@Test
	public void testReadWebXML() {
		try {
			//1.获取解析器
			SAXReader saxReader = new SAXReader();
			//2.获取document文档对象
			Document doc = saxReader.read("src/cn/aynortechnology/xml/dtd/web.xml");
			//3.获取根元素
			Element rootElement = doc.getRootElement();
			//System.out.println(rootElement.getName());//获取根元素名称
			//System.out.println(rootElement.attributeValue("version"));//获取根元素中的属性值
			//4.获取根元素下的子元素
			List<Element> childElements = rootElement.elements();
			//5.遍历子元素
			for (Element element : childElements) {
				//6.判断元素名称为servlet的元素
				if("servlet".equals(element.getName())) {
					//7.获取servlet-name元素
					Element servletName = element.element("servlet-name");
					//8.获取servlet-class元素
					Element servletClass = element.element("servlet-class");
					//9.getservlet文本打印
					System.out.println(servletName.getText());
					System.out.println(servletClass.getText());
				}
			}
		} catch (DocumentException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
	}
}

反射
由于程序已经运行,无法在其中进行new对象的建立,就无法使用对象。这是可以根据配置文件类全名去找对应的字节码文件,并加载进内存,并创建该类对象实例。这就需要使用反射技术完成。在运行状态中获取一个类(动态获取),并获取它的属性和方法,也可以调用这些属性和方法,使用反射可以在运行时对类,构造方法,普通方法和进行操作。

接口代码

package cn.aynortechnology.web.servlet;

public interface IMyServlet {
	public void init();
	
	public void service();
	
	public void destory();

}

实现接口的类

package cn.aynortechnology.web.servlet;

public class MyServletImpl implements IMyServlet {

	@Override
	public void init() {
		// TODO 自动生成的方法存根
		System.out.println("1");
	}

	@Override
	public void service() {
		// TODO 自动生成的方法存根
		System.out.println("2");
	}

	@Override
	public void destory() {
		// TODO 自动生成的方法存根
		System.out.println("3");
	}

}

模拟读取配置文件

package cn.aynortechnology.web.servlet;

import org.junit.Test;

public class TestMyServlet {
	@Test
	public void testMyServlet() {
		MyServletImpl my = new MyServletImpl();
		my.init();
		my.service();
		my.destory();
	}
	
	@Test
	public void testMyServlet1() {
		try {
			//假设从配置文件中获取了这个类的全名
			String className = "cn.aynortechnology.web.servlet.MyServletImpl";
			Class clazz = Class.forName(className);
			MyServletImpl my = (MyServletImpl)clazz.newInstance();
			my.init();
			my.service();
			my.destory();
		} catch (Exception e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}	
	}
}

通过读取配置文件的方法来使反射完成对对象的调用
接口与上面相同
实现接口的类

package cn.aynortechnology.web.seevlet1;

public class MyServlet1 implements IMyServlet{

	@Override
	public void init() {
		// TODO 自动生成的方法存根
		System.out.println("Servlet1初始化完毕");
	}

	@Override
	public void service() {
		// TODO 自动生成的方法存根
		System.out.println("Servlet1正在服务");
	}

	@Override
	public void destory() {
		// TODO 自动生成的方法存根
		System.out.println("Servlet1已销毁");
	}

}

重新编写web.xml文档

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app SYSTEM "web-app_2_3.dtd">
<web-app version="1.0">
	<servlet>
		<servlet-name>myServlet1</servlet-name>
		<servlet-class>cn.aynortechnology.web.seevlet1.MyServlet1</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>myServlet1</servlet-name>
		<url-pattern>/MyServlet1</url-pattern>
	</servlet-mapping>
	<servlet>
		<servlet-name>myServlet2</servlet-name>
		<servlet-class>cn.aynortechnology.web.seevlet1.MyServlet2</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>myServlet2</servlet-name>
		<url-pattern>/MyServlet2</url-pattern>//这里必须有斜杠
	</servlet-mapping>
</web-app>

XML文档使用的DTD约束如下

<?xml version="1.0" encoding="UTF-8"?>
<!--
	模拟serblet2.3规范,如果开发人员需要在xml使用当前DTD约束,必须包括DOCTYPE。
	格式如下:
	<!DOCTYPE web-app SYSTEM "web-app_2_3.dtd">
-->
<!ELEMENT web-app (servlet*,servlet-mapping*,welcome-file-list?)>
<!ELEMENT servlet (servlet-name,description?,(servlet-class|jsp-file))>
<!ELEMENT servlet-mapping (servlet-name,url-pattern+)>
<!-- #PCDATA为只能出现文本 -->
<!ELEMENT servlet-name (#PCDATA)>
<!ELEMENT servlet-class (#PCDATA)>
<!ELEMENT url-pattern (#PCDATA)>
<!ELEMENT description (#PCDATA)>
<!ELEMENT jsp-file (#PCDATA)>

<!ELEMENT welcome-file-list (welcome-file+)>
<!ELEMENT welcome-file (#PCDATA)>

<!ATTLIST web-app version CDATA #IMPLIED>

测试,一整套流程

package cn.aynortechnology.web.seevlet1;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;

public class TestMyServlet {

	
	@Test
	public void testMyServlet() {
		try {
			//1.创建解析器对象
			SAXReader saxReader = new SAXReader();
			//2.通过解析器来加载web.xml文件,得到document对象
			Document document = saxReader.read("src/cn/aynortechnology/web/seevlet1/web.xml");
			//3.获取根元素节点
			Element rootElement = document.getRootElement();
			//4.根据元素名称获取子元素节点
			Element servletelement = rootElement.element("servlet");
			//5.根据元素名称获取servlet-class的文本节点
			String servletClass = servletelement.element("servlet-class").getText();
			System.out.println("已获取Class名称:"+servletClass);
			//6.通过类全名获取字节码文件
			Class clazz = Class.forName(servletClass);
			//7.创建实例对象
			MyServlet1 my = (MyServlet1) clazz.newInstance();
			//8.调用实例对象里面的方法
			my.init();
			my.service();
			my.destory();
		} catch (Exception e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
	}
}

使用JUnit测试运行,输出如下
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值