天天看點

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;

	}

}

           
xml