JavaWeb--XML的解析(1)

一、XML解析的技术

  1. DOM
  2. SAX

针对这两种解析技术,官方以及其他组织提供了不同的实现方式

常见的解析方式有如下三种:

a. sun公司提供的jaxp

b. dom4j组织提供的dom4j

c. jdom组织提供的jdom

二、dom VS sax

 dom方式解析
			* 根据xml的层级结构在内存中分配一个树形结构,把xml的标签,属性和文本都封装成对象
			* 缺点:如果文件过大,造成内存溢出
			* 优点:很方便实现增删改操作

 sax方式解析
			* 采用事件驱动,边读边解析:从上到下,一行一行的解析,解析到某一个对象,返回对象名称
			* 缺点:不能实现增删改操作
			* 优点:如果文件过大,不会造成内存溢出,方便实现查询操作

三、jaxp所依赖的类

jaxp是javase的一部分
jaxp解析器在jdk的javax.xml.parsers包里面

Dom技术所依赖的两个类:
	DocumentBuilderFactory: 解析器工厂类。这是一个抽象类,不能实例化
					   通过newInstance() 方法来获取 DocumentBuilderFactory 的实例。
	DocumentBuilder  : 解析器类。这个类也是一个抽象类,不能实例化
				 此类的实例可以从 DocumentBuilderFactory.newDocumentBuilder() 方法获取

sax技术所依赖的两个类:
	SAXParserFactory: 解析器工厂。实例 newInstance() 方法得到
	SAXParser:解析器类。实例可以从 SAXParserFactory.newSAXParser() 方法获得

四、jaxp利用DOM技术解析XML文件实例

现有如下xml文件

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<person>
	<p>
		<name>zhangsan</name>
	</p>
	
	<p>
		<name>lisi</name>
		<gender>m</gender>
	</p>
</person>

操作一:查询xml文件中所有name元素的文本值

private static void selectAll() throws Exception {
		//创建解析器工厂对象
		DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
		
		//获取解析器对象
		DocumentBuilder builder = builderFactory.newDocumentBuilder();
		
		//获取解析后的document对象
		Document doc = builder.parse("F:/MyEclipse10.7/Day05/src/testJaxp/person.xml");
		
		//获取所有name元素
		NodeList list = doc.getElementsByTagName("name");
		
		//输出name元素中的文本对象值
		Node temp = null;
		for(int i=0; i<list.getLength(); i++){
			temp = list.item(i);					//获取每一个Node对象
			String str = temp.getTextContent();		//获取每一个Node对象的content
			System.out.println(str);
		}
}

所用到的方法:

DocumentBuilderFactory.newInstance():创建解析器工厂类实例
builderFactory.newDocumentBuilder():创建解析器实例
builder.parse:解析器调用解析方法,返回解析后的Document对象
doc.getElementsByTagName("标签名"):document对象调用该方法,获取所有指定标签名的标签,返回类型为NodeList
list.getLength():NodeList对象调用该方法,返回该List的长度
list.item(索引):NodeList对象调用该方法,根据下标返回指定Node对象
getTextContent():标签对象调用该方法,返回该标签的文本值

操作二:在第一个p元素中插入一个gender元素,其中gender元素的文本值为f

public static void addGender() throws Exception{
		//获取解析器工厂对象
		DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
		
		//获取解析器对象
		DocumentBuilder builder = builderFactory.newDocumentBuilder();
		
		//获取解析后的document对象
		Document doc = builder.parse("F:/MyEclipse10.7/Day05/src/testJaxp/person.xml");
		
		//获取第一个p元素
		NodeList list = doc.getElementsByTagName("p");
		Node p1 = list.item(0);
		
		//创建一个gender元素对象
		Element gender1 = doc.createElement("gender");
		
		//创建一个文本对象
		Text text1 = doc.createTextNode("f");
		
		//将文本对象加入gender元素
		gender1.appendChild(text1);
		
		//将gender元素加入到p元素
		p1.appendChild(gender1);
		
		//获取回写工厂对象
		TransformerFactory transformerFactory = TransformerFactory.newInstance();
		
		//获取回写对象
		Transformer transformer = transformerFactory.newTransformer();
		
		//调用回写方法将内存中的document对象写入到xml文件
		transformer.transform(new DOMSource(doc), new StreamResult("F:/MyEclipse10.7/Day05/src/testJaxp/person.xml"));
}

所用到的方法:

doc.createElement("标签名"):Document对象调用该方法,返回创建好的标签对象
doc.createTextNode("文本值"):Document对象调用该方法,返回创建好的文本对象
appendChild(对象名):父类对象调用该方法,将指定对象名的对象插入到该父类对象
TransformerFactory.newInstance():获取回写工厂类对象
transformerFactory.newTransformer():获取回写对象
transformer.transform(new DOMSource(doc), new StreamResult("F:/MyEclipse10.7/Day05/src/testJaxp/person.xml")):
回写对象调用该回写方法,参数分别为源对象,和目的对象
参数一:Source的实现类
参数二:Result的实现类

操作三:修改第一个gender元素中的content对象为m

public static void modifyGender() throws Exception{
		//获取解析器工厂对象
		DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
		
		//获取解析器对象
		DocumentBuilder builder = builderFactory.newDocumentBuilder();
		
		//获取解析后的document对象
		Document doc = builder.parse("F:/MyEclipse10.7/Day05/src/testJaxp/person.xml");
		
		//获取第一个gender元素
		Node gender = doc.getElementsByTagName("gender").item(0);
		
		//使用setTextContent方法修改文本对象内容
		gender.setTextContent("m");
		
		//回写
		TransformerFactory formerFactory = TransformerFactory.newInstance();
		Transformer transformer = formerFactory.newTransformer();
		transformer.transform(new DOMSource(doc), new StreamResult("F:/MyEclipse10.7/Day05/src/testJaxp/person.xml"));
	}

用到的方法:

setTextContent("文本内容"):标签对象调用该方法,修改自己的文本值

操作四:删除第一个p1元素下面的gender元素

public static void removeGender() throws Exception{
		//获取解析器工厂对象
		DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
		
		//获取解析器 对象
		DocumentBuilder builder = builderFactory.newDocumentBuilder();
		
		//获取解析后的document对象
		Document doc = builder.parse("F:/MyEclipse10.7/Day05/src/testJaxp/person.xml");
		
		//获取gender元素
		Node gender = doc.getElementsByTagName("gender").item(0);
		
		//获取gender得父节点
		Node p = gender.getParentNode();
		
		//父节点使用removeChild方法
		p.removeChild(gender);
		
		//回写
		TransformerFactory formerFactory = TransformerFactory.newInstance();
		Transformer transformer = formerFactory.newTransformer();
		transformer.transform(new DOMSource(doc), new StreamResult("F:/MyEclipse10.7/Day05/src/testJaxp/person.xml"));
}

用到的方法:

getParentNode():标签对象调用该方法,获取自己的父标签
removeChild(标签对象名):父标签调用该方法,删除指定标签名的子标签

五、jaxp利用SAX技术解析XML文件实例

  1. 创建解析器,并执行parse方法的实例
public class TeachSax {
	public static void main(String[] args) throws Exception {
		/*
		 * 1、创建解析器工厂
		 * 2、创建解析器
		 * 3、执行parse方法
		 * */
		//创建解析器工厂
		SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
		//创建解析器
		SAXParser saxParser = saxParserFactory.newSAXParser();
		//执行parse方法
		saxParser.parse("F:/MyEclipse10.7/Day06/src/zuobiao/sax/person.xml", new MyDefault1());	
	}
}

/**
	自己创建一个类,继承DefaultHandler
	重写类里面的三个方法(有时候需要5个)
*/
class MyDefault1 extends DefaultHandler {
	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		System.out.print("<"+qName+">");
	}
	
	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		System.out.print(new String(ch,start,length));
	}

	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		System.out.print("</"+qName+">");
	}
}

用到的方法:

SAXParserFactory.newInstance():创建解析类工厂对象
saxParserFactory.newSAXParser():获取解析类对象
parse(参数1, 参数2):解析XML文档
两个参数
	- 第一个参数:xml的路径
	- 第二个参数:事件处理器(该处理器需要继承自DefaultHandler,并重写里面的方法)
	
事件处理类:
DefaultHandler	
	- startDocument:当XML文档开始解析时该方法被自动调用
	- startElement:当开始解析一个元素时,该方法被自动调用
	- characters:当解析到文本内容时,该方法被自动调用
	- endElement:当解析一个元素结束时,该方法被自动调用
	- endDocument:当XML文档解析结束时该方法被自动调用

  1. sax解析xml文档操作实例

现有如下xml文件

<?xml version="1.0" encoding="UTF-8"?>
<person> 
  <p1> 
    <name>zhangsan</name>  
    <age>20</age>  
  </p1>  
  <p1> 
    <name>lisi</name>  
    <age>30</age> 
  </p1> 
</person>

操作一:输出xml文件中的所有内容

事件处理类如下:

class MyDefaultHandler1 extends DefaultHandler{
	@Override
	public void startDocument() throws SAXException {
		System.out.println("<?xml version='1.0' encoding='utf-8'?>");
	}
    
	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		System.out.print("<"+qName+">");
	}
	
	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		System.out.print(new String(ch,start,length));
	}
	
	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		System.out.print("</"+qName+">");
	}
    
    @Override
	public void characters(char[] ch, int start, int length)
				throws SAXException {
		System.out.print(new String(ch, start, length));
	}
}

main方法中调用:

public class TestSax {
	public static void main(String[] args) throws Exception{
		//获取SaxParserFactory对象
		SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
		
		//获取SaxParser对象
		SAXParser parser = saxParserFactory.newSAXParser();
		
		//使用parser方法解析xml文件
		parser.parse("F:/MyEclipse10.7/Day06/src/zuobiao/sax/person.xml", new MyDefaultHandler1());
	}
}

操作二:输出指定索引的name标签文本值

事件处理类如下:

class MyDefaultHandler2 extends DefaultHandler{
	boolean flag = false;	//使用标记来记录是否为name标签
	int index = 0;		    //使用index来继承name标签的索引值
	
	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		if("name".equals(qName)){
			this.flag = true;
			index++;
		}
	}
	
	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		if(flag && (index==2)){
			System.out.println(new String(ch,start,length));
		}
	}
	
	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		if("name".equals(qName)){
			this.flag = false;
		}
	}
}

main方法中调用同上,故省略。

参考博文在此

Java新手,若有错误,欢迎指正!

posted @ 2020-04-10 18:13  跑调大叔!  阅读(176)  评论(0编辑  收藏  举报