基本概念
什么是xml文件?
1.概念:
可扩展标记语言。作为数据的一种存储格式用于存储软件的参数。
2.xml和html的区别:
- xml 重点:描述和存放数据。
- html 重点:如何把数据更好的现实在页面上。
3.xml的标记分类:
- 单标记<标记名称 />
- 双标记<标记名称>…</标记名称>
注意:如果标记内封装了其他字标记或内容,那么该标记一定是双标记。
4.标记的命名规则:
-
标记名称必须以字母或下划线开头,后边包含字母、数字、下划线。
-
标记名称必须严格区分大小写。
-
标记必须顺序嵌套。
5.xml属性规则:
- 属性名 = “属性值”。
- 属性名必须以字母或下划线开头,后边可以有数字,字母、下划线;
- 属性值必须括在引文的引号之内。
- 属性名称必须唯一。
xml文件示例:
<?xml version="1.0" encoding="UTF-8" ?>
<web-app>
<servlet>
<servlet-name>login</servlet-name>
<servlet-class>webxml.LoginServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>reg</servlet-name>
<servlet-class>webxml.RegisterServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/g</url-pattern>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>reg</servlet-name>
<url-pattern>/reg</url-pattern>
</servlet-mapping>
</web-app>
SAX解析xml文档
什么是SAX解析?
SAX,全称Simple API for XML,是一种以事件驱动的XMl API,是XML解析的一种新的替代方法,解析XML常用的还有DOM解析,PULL解析(Android特有),SAX与DOM不同的是它边扫描边解析,自顶向下依次解析,由于边扫描边解析,所以它解析XML具有速度快,占用内存少的优点,对于Android等CPU资源宝贵的移动平台来说是一个巨大的优势。
SAX解析xml文件思路
(以上面示例中的webxml文件为例)
解析思路:
1.每遇到一个 < servlet >标签,可以根据该标签下对应的属性标签,将其加入到一个集合中。前提是要根据标签写好对应封装好的javabean,即可直接在容器中加入该对象。
2.由url-pattern(路径)—>(得到)Servlet-name(名称)—>Servlet-class(类名)。
需要用到的知识点:
1.java集合
2.java反射
3.java封装思想
SAX解析xml文件的步骤
- start Document(): -->解析文档开始
具体:新建一个list,以便之后存储文档中的多个用户存储。 - start Element(): -->解析标签开始
每遇到一个< servlet >或者< servlet-mapping> 标签,就要新建一个对应标签的对象。(前提是已经写好了对应的javabean) - start character: -->解析标签及内容
每个< servlet >或者< servlet-mapping> 标签下都有对应属性下的内容。每解析到对应属性,九江属性标签下的内容设置到当前对象的属性中。 - end Element(qname)
每遇到< /servlet>或者< /servlet-mapping>时,便可以将当前对象加入到list中。 - 解析结束。
代码示例
1.解析代码:
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.util.ArrayList;
import java.util.List;
public class WebXmlTest {
public static void main(String[] args) throws Exception {
SAXParserFactory factory1 = SAXParserFactory.newInstance();
SAXParser parser1 = factory1.newSAXParser();
//注册处理器
webHandler handler = new webHandler();
parser1.parse(Thread.currentThread().getContextClassLoader().getResourceAsStream("web.xml")
,handler);
WebContext context = new WebContext(handler.getEntities(),handler.getMapings());
//假设你输入了/login
//这里用了反射奥
String className = context.getClz("/reg");
Class clz = Class.forName(className);
System.out.println(className);
// List<Entity> entities = handler.getEntities();
// List<Maping> mapings = handler.getMapings();
// System.out.println(entities.size());
// System.out.println(mapings.size());
}
}
class webHandler extends DefaultHandler{
List<Entity> entities = new ArrayList<>();
List<Maping> mapings = new ArrayList<>();
Entity entity;
Maping maping;
String currentTag;
private boolean isMapping = false;
public webHandler() {
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if(null!=qName){
currentTag = qName;
if(qName.equals("servlet")){
entity = new Entity();
isMapping = false;
}else if(qName.equals("servlet-mapping")){
maping = new Maping();
isMapping = true;
}
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
//System.out.println("!");
if(null!=qName){
if(qName.equals("servlet-mapping")){
mapings.add(maping);
}else if(qName.equals("servlet")){
entities.add(entity);
}
}
currentTag = null;
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
String value = new String(ch, start, length).trim();
if (null != currentTag) {
if (!isMapping) {
if (currentTag.equals("servlet-name")) {
entity.setName(value);
} else if (currentTag.equals("servlet-class")) {
if(value.length()>0) {
entity.setClz(value);
}
}
} else {
if (currentTag.equals("servlet-name")) {
maping.setName(value);
} else if (currentTag.equals("url-pattern")) {
maping.addPattern(value);
}
}
}
}
public List<Entity> getEntities() {
return entities;
}
public List<Maping> getMapings() {
return mapings;
}
}
2.javabean代码:
public class Entity {
private String name;
private String clz;
public Entity(String name, String clz) {
this.name = name;
this.clz = clz;
}
public Entity() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getClz() {
return clz;
}
public void setClz(String clz) {
this.clz = clz;
}
}
public class Maping {
private String name;
private Set<String> patterns; //url-pattern中的元素不重复
public Maping(String name, Set<String> patterns) {
this.name = name;
this.patterns = patterns;
}
public Maping(){
patterns = new HashSet<String>();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<String> getPatterns() {
return patterns;
}
public void setPatterns(Set<String> patterns) {
this.patterns = patterns;
}
public void addPattern(String pattern){
this.patterns.add(pattern);
}
}
注意:
解析时,每遇到一个endElement时都要将当前标签设置为空。
否则 < /servlet-name > ……(空) < servlet-class >之间的内容也会被解析。
利用反射处理webxml文件中的数据
基本过程
1.通过< servlet -mapping>中的URL(唯一)找到 Servlet-name。
2.通过name在Servlet中找到对应的class。
实现该过程要用到的方法
利用HashMap中键值对对应的方法。
代码
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class WebContext {
private List<Entity> entitys = null;
private List<Maping> mapings = null;
//key-->servlet-name value-->servlet-class
private Map<String,String> entityMap = new HashMap<String,String>();
//key-->url-pattern value-->servlet-name
private Map<String,String> mappingMap = new HashMap<String,String>();
public WebContext(List<Entity> entitys, List<Maping> mapings) {
this.entitys = entitys;
this.mapings = mapings;
//将entity的list转成对应的map
for(Entity entity:entitys){
entityMap.put(entity.getName(),entity.getClz());
}
//将map的list转成对应的map
for(Maping maping:mapings){
for(String pattern:maping.getPatterns()){
mappingMap.put(pattern,maping.getName());
}
}
}
/**
* 通过URL的路径找到对应class
* 1.通过url找到name
* 2.通过name找到对应的class
*
*/
public String getClz(String pattern){
String name = mappingMap.get(pattern);
return entityMap.get(name);
}
}