XML解析:SAX解析/DOM解析/DOM4j解析

xml解析:
原生解析:
SAX解析:

	特点:
		基于事件处理机制的解析(sax)
		(1)边读边解析
		(2)不能回读,如果遇到未处理的事件,要重新读取
		(3)轻量级,速度快
		(4)适合处理较大的xml文档
		(5)只能读取,不能修改

	步骤:
		SAXParserFactory  创建SaxparserFacory工厂:这个工厂是用来产生SAXParser实例
		SAXParser  sax解析器
		parse(File f, HandlerBase hb);
		DefaultHandler   默认的处理类   需要写一个类继承它

		默认处理类中常用方法:
		1, startDocument();   这个方法只是在解析xml的时候执行一次
		2, endDocument();	   解析xml结束时调用,只调用一次
		//	遇到开始标签调用该方法,调用n次
		3, startElement(String uri, String localName, String qName,Attributes attributes)
			  uri:指向一个唯一的地址  一般不使用
			  localName  加上命名空间的名字,如果没有设置命名空间,值为null
			  qName:当前标签名
			  attributes:封装了开始标签中属性的信息
			  attributes.getQName(i);拿到第几个属性的属性名
			  attributes.getValue(i);拿到第几个属性的属性值
			  attributes.getLength();该标签属性的个数
		4, endElement();遇到结束标签的时候调用
		5, characters(char[] ch, int start, int length);遇到文本域的时候执行该方法

代码:

package com.xml.ch2.work;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class Sax_Student_xml{
	public static void main(String[] args) {
		ArrayList<Student> list = new ArrayList<>();
		SAXParser parser = null;
		SAXParserFactory factory = SAXParserFactory.newInstance();
		try {
			 parser = factory.newSAXParser();
		} catch (ParserConfigurationException | SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			parser.parse("src/com/xml/ch2/work/student.xml", new MySaxListener());
		} catch (SAXException | IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		List<String> filtered =MySaxListener.list.stream().filter(string -> !string.isEmpty())
				.collect(Collectors.toList());
		System.out.println(filtered);
		SaxToStudent(filtered,list);
		System.out.println(list);
	}
	public static List<Student> SaxToStudent(List<String> list, List<Student> ls) {
		Iterator<String> iterator = list.iterator();
		while (iterator.hasNext()) {
			Student student = new Student(iterator.next(), iterator.next(), iterator.next(),
					Integer.parseInt(iterator.next()), iterator.next(),
					new Address(iterator.next(), iterator.next(), iterator.next()));
			ls.add(student);
		}
		return ls;
	}
}
class MySaxListener extends DefaultHandler{
	public static List<String> list=null;
	
	 // 文档开始解析时自动调用该方法
    @Override
    public void startDocument() throws SAXException {
       list=new ArrayList<String>();
    }

    // 开始解析元素时,自动调用此方法
    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        //System.out.print("<" + qName);
        for (int i = 0; i < attributes.getLength(); i++) {
//            System.out.print(" " + attributes.getLocalName(i) + "=\""
//                    + attributes.getValue(i) + "\"");
            list.add(attributes.getValue(i));
        }
        System.out.print(">");
    }

    // 元素解析结束时自动调用该方法
    @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 {
    	list.add(new String(ch, start, length).trim());
       // System.out.print(new String(ch, start, length));
    }

    // 文档解析结束时自动调用该方法
    @Override
    public void endDocument() throws SAXException {
        //System.out.println("文档解析结束..");
    }
}

DOM解析:

特点:
	基于树形结构的解析(dom)
	(1)先将整个xml文档加载到内存,形成树形结构,再解析
	(2)可以重复读取
	(3)重量级,速度慢
	(4)适合处理较小的xml文档
	(5)能够进行增、删、改、查
	

创建xml文件:

	1.使用DOM方式创建students.xml 
		原则:就是使用Doc对象去创建各种Node,Attribute和createTextNode(),然后将节点append到相应的标签后面

		DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
		Document doc = builder.newDocument();//创建新doc对象
		主要使用的方法:
			Attr name =doc.createAttribute("属性名");
			name.setValue("属性值");
			标签.setAttributeNode(name);//给标签添加一个Attr对象

			标签.setAttribute("属性名","属性值");//给标签设置一个属性 key=value

			Element teacher=doc.createElement("标签名");//创建标签 现在只是单单创建了一个标签 没有追加到任何父标签后面
			Text hao=doc.createTextNode("文本值");//创建文本 同上
			父标签.appendChild(节点);//追加, 将文本或者标签追加到父标签下

		将创建的xml写到文件中 需要导入包:crimson.jar
		FileWriter fw = new FileWriter("src/teacher.xml");
		((XmlDocument)doc).write(fw);

	2.使用Writer的方式直接写出去一个xml文件
		//1获得写出对象
		XMLStreamWriter writer = XMLOutputFactory.newFactory().createXMLStreamWriter(new FileOutputStream("src/aaa.xml"));
		常用方法:
			writer.writeStartDocument("utf-8", "1.0");//写xml的指令
			writer.writeEndDocument();//写结束指令
			writer.writeStartElement("students");//写一个开始标签
			writer.writeEndElement();//写一个结束标签
			writer.writeAttribute("one", "这个是一个单独的子标签");//写一个属性在上面的标签中
			writer.writeCharacters("文本 还是很好看的");//写一个文本
	3.删除xml文件的节点:
		removeChild()
		removeAttribute(String name)

代码:

package com.xml.ch2.work.dom;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.xml.ch2.work.Address;
import com.xml.ch2.work.Student;

public class DomToStudent {
	public static void main(String[] args) {
		ArrayList<String> list = new ArrayList<>();
		ArrayList<Student> list2 = new ArrayList<>();
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = null;
		Document dom = null;
		try {
			builder = factory.newDocumentBuilder();
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			dom = builder.parse("src/com/xml/ch2/work/student.xml");
		} catch (SAXException | IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		NodeList stulist = dom.getElementsByTagName("stu");
		for (int i = 0; i < stulist.getLength(); i++) {
			Node item = stulist.item(i);
			Iterator(item, list);
			
			/*
			 * NodeList childNodes = item.getChildNodes();
			 * System.out.println(childNodes.getLength()); if (childNodes != null &&
			 * childNodes.getLength() > 0) { for (int j = 0; j < childNodes.getLength();
			 * j++) { Node item2 = childNodes.item(j); System.out.println(item2); NodeList
			 * childNodes2 = item.getChildNodes(); } } else { String text1 =
			 * item.getTextContent(); list.add(text1); }
			 */
		}
		List<String> filtered =list.stream().filter(string -> !string.isEmpty())
				.collect(Collectors.toList());
		DomToStudent(filtered,list2);
		System.out.println(filtered);
		System.out.println(list2);
		
	}
	public static List<Student> DomToStudent(List<String> list, List<Student> ls) {
		Iterator<String> iterator = list.iterator();
		while (iterator.hasNext()) {
			Student student = new Student(iterator.next(), iterator.next(), iterator.next(),
					Integer.parseInt(iterator.next()), iterator.next(),
					new Address(iterator.next(), iterator.next(), iterator.next()));
			ls.add(student);
		}
		return ls;
	}

	public static List<String> Iterator(Node node, List<String> ls) {
		if(node.hasAttributes()) {
			NamedNodeMap attributes = node.getAttributes();
			for (int i = 0; i < attributes.getLength(); i++) {
				Node item = attributes.item(i);
				ls.add(item.getNodeValue());
			}
		}
		if(node.hasChildNodes()) {
			NodeList childNodes = node.getChildNodes();
			for (int i = 0; i < childNodes.getLength(); i++) {
				Iterator(childNodes.item(i), ls);
			}
		}
		else {
			ls.add(node.getTextContent().trim());
		}
		return ls;
	}

}

第三方解析:

DOM4J解析:

  1. 需要引入jar包 —> dom4j-16.1.jar
    怎么引入jar包?
    1.1首先需要有一个java program ,然后左键单击选中项目,右键new一个Folder取名为jar
    1.2然后把想引入的jar包复制到刚才新建的folder下面
    1.3选中想依赖到项目中的jar包,右键 选中build Path 然后点击 add to build Path
    1.4 依赖完成 —>jar包已经添加到项目中

  2. 创建dom4j解析器对象 SAXReader s = new SAXReader();

  3. 使用解析器对象解析xml文件 Document doc = s.read(“文件路径+文件名”);//这个对象代表整个文档, 但是还不是文档是根节点

  4. 获取xml文档的根节点 Element root = doc.getRootElement();

  5. 获取根节点的所有孩子节点 List list = root.elements();

  6. (可选)获取属性所对应的值 String attribute = item.getAttribute(“属性名”);

  7. (可选)获取本节点下的孩子节点 List list2 = e1.elements();//就是本次把e1当做是根节点 然后获取根节点下面的子节点

  8. (可选)获取当前标签的标签名 e1.getName();

  9. (可选)获取当前标签的文本值 e1.getText();

  10. (可选)获取当前标签下所有的文本值 e1.getStringValue();

代码:

package com.xml.ch2.work;

import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class Student_xml {
	public static void main(String[] args) throws Exception {
		List<String> list = new ArrayList<String>();
		List<Student> stulist = new ArrayList<>();
		SAXReader r = new SAXReader();
		Document doc = r.read("src/com/xml/ch2/work/student.xml");
		Element root = doc.getRootElement();
		List<Element> stus = root.elements();
		for (Element stu : stus) {
			String sid = stu.attributeValue("sid");
			list.add(sid);
			Iterator(stu,list);
		}
		Dom4JToStudent(list,stulist);
		System.out.println(list);
		System.out.println(stulist);
	}

	public static List<Student> Dom4JToStudent(List<String> list, List<Student> ls) {
		Iterator<String> iterator = list.iterator();
		while (iterator.hasNext()) {
			Student student = new Student(iterator.next(), iterator.next(), iterator.next(),
					Integer.parseInt(iterator.next()), iterator.next(),
					new Address(iterator.next(), iterator.next(), iterator.next()));
			ls.add(student);
		}
		return ls;
	}

	public static List<String> Iterator(Element e, List<String> ls) {
		List<Element> list = e.elements();
		if (list != null && list.size() > 0) {
			for (Element e2 : list) {
				Iterator(e2, ls);
			}
		}
		if (e.getTextTrim().equals("")) {

		} else {
			ls.add(e.getTextTrim());
		}
		return ls;

	}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值