xml解析



title: xml的解析
tags:
grammar_cjkRuby: true

解析xml有三種方法
1.原生的dom解析,這個方法不常用。
2.dom4j開源庫,還可以加上jaxen-1.1的jar包,適合xPath解析表達式。能讀能寫
3.sax解析,這個適合大體積的文件,缺點是只能解析,而且只能順序讀。

dom4j的主要api:

讀取xml文檔	
SAXReader reader = new SAXReader();
InputStream in = Object.class.getResourceAsStream("/test.properties");
Document doc = reader.read(in);
或者
Document doc = reader.read(new File("./src/contact.xml"));
doc.read();//可以讀取file,inputstream等
//節點:
Iterator  Element.nodeIterator();  //獲取當前標簽節點下的所有子節點

//標簽:
Element  Document.getRootElement();  //獲取xml文檔的根標簽		
Element   ELement.element("標簽名") //指定名稱的第一個子標簽
Iterator<Element> Element.elementIterator("標簽名");// 指定名稱的所有子標簽
List<Element>	 Element.elements(); //獲取所有子標簽

//屬性:
String   Element.attributeValue("屬性名") //獲取指定名稱的屬性值
Attribute    Element.attribute("屬性名");//獲取指定名稱的屬性對象	
Attribute.getName()  //獲取屬性名稱
Attibute.getValue()  //獲取屬性值
List<Attribute>	 Element.attributes();  //獲取所有屬性對象
Iterator<Attribute>		Element.attibuteIterator(); //獲取所有屬性對象

//文本:
Element.getText();  //獲取當前標簽的文本
Element.elementText("標簽名") //獲取當前標簽的指定名稱的子標簽的文本內容

// 使用xpath方法
List<Node>  selectNodes("xpath表達式");   查詢多個節點對象
Node       selectSingleNode("xpath表達式");  查詢一個節點對象

修改文件

2.1 寫出內容到xml文檔
XMLWriter writer = new XMLWriter(OutputStream, OutputForamt)
wirter.write(Document);

2.2 修改xml文檔的API
增加: 
    DocumentHelper.createDocument()  增加文檔
    addElement("名稱")  增加標簽
    addAttribute("名稱",“值”)  增加屬性
修改:
    Attribute.setValue("值")  修改屬性值
    Element.addAtribute("同名的屬性名","值")  修改同名的屬性值
    Element.setText("內容")  修改文本內容
刪除
    Element.detach();  刪除標簽  
    Attribute.detach();  刪除屬性

下面是一些實例代碼:

讀取文件內容

package gz.itcast.a_dom4j_read;

import java.io.File;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Test;

/**
 * 第二個dom4j讀取xml文件內容
 * 節點
 * 標簽
 * 屬性
 * 文本
 * @author APPle
 *
 */
public class Demo2 {
	
/**
 * 得到節點信息
 */
@Test
public void test1() throws Exception{
	//1.讀取xml文檔,返回Document對象
	SAXReader reader = new SAXReader();
	Document doc = reader.read(new File("./src/contact.xml"));
	
	//2.nodeIterator: 得到當前節點下的所有子節點對象(不包含孫以下的節點)
	Iterator<Node> it = doc.nodeIterator();
	while(it.hasNext()){//判斷是否有下一個元素
		Node node = it.next();//取出元素
		String name = node.getName();//得到節點名稱
		//System.out.println(name);
		
		//System.out.println(node.getClass());
		//繼續取出其下面的子節點
		//只有標簽節點才有子節點
		//判斷當前節點是否是標簽節點
		if(node instanceof Element){
			Element elem = (Element)node;
			Iterator<Node> it2 = elem.nodeIterator();
			while(it2.hasNext()){
				Node n2 = it2.next();
				System.out.println(n2.getName());
			}
		}
	}
}

/**
 * 遍歷xml文檔的所有節點
 * @throws Exception
 */
@Test
public void test2() throws Exception{
	//1.讀取xml文檔,返回Document對象
	SAXReader reader = new SAXReader();
	Document doc = reader.read(new File("./src/contact.xml"));
	//得到根標簽
	Element rooElem = doc.getRootElement();
	getChildNodes(rooElem);
}

/**
 * 獲取 傳入的標簽下的所有子節點
 * @param elem
 */
private void getChildNodes(Element elem){
	System.out.println(elem.getName());
	//得到子節點
	Iterator<Node> it = elem.nodeIterator();
	while(it.hasNext()){
		Node node = it.next();
		
		//1.判斷是否是標簽節點
		if(node instanceof Element){
			Element el = (Element)node;
			//遞歸
			getChildNodes(el);
		}
	};
}

/**
 * 獲取標簽
 */
@Test
public void test3() throws Exception{
	//1.讀取xml文檔,返回Document對象
	SAXReader reader = new SAXReader();
	Document doc = reader.read(new File("./src/contact.xml"));
	
	//2.得到根標簽
	Element  rootElem = doc.getRootElement();
	//得到標簽名稱
	String name = rootElem.getName();
	System.out.println(name);
	
	//3.得到當前標簽下指定名稱的第一個子標簽
	/*
	Element contactElem = rootElem.element("contact");
	System.out.println(contactElem.getName());
	*/
	
	//4.得到當前標簽下指定名稱的所有子標簽
	/*
	Iterator<Element> it = rootElem.elementIterator("contact");
	while(it.hasNext()){
		Element elem = it.next();
		System.out.println(elem.getName());
	}
	*/
	
	//5.得到當前標簽下的的所有子標簽
	List<Element> list = rootElem.elements();
	//遍歷List的方法
	//1)傳統for循環  2)增強for循環 3)迭代器
	/*for(int i=0;i<list.size();i++){
		Element e = list.get(i);
		System.out.println(e.getName());
	}*/
	
/*	for(Element e:list){
		System.out.println(e.getName());
	}*/
	/*
	Iterator<Element> it = list.iterator(); //ctrl+2 松開 l
	while(it.hasNext()){
		Element elem = it.next();
		System.out.println(elem.getName());
	}*/
	
	//獲取更深層次的標簽(方法只能一層層地獲取)
	Element nameElem = doc.getRootElement().
				element("contact").element("name");
	System.out.println(nameElem.getName());
	
}

/**
 * 獲取屬性
 */
@Test
public void test4() throws Exception{
	//1.讀取xml文檔,返回Document對象
	SAXReader reader = new SAXReader();
	Document doc = reader.read(new File("./src/contact.xml"));
	
	//獲取屬性:(先獲的屬性所在的標簽對象,然后才能獲取屬性)
	//1.得到標簽對象
	Element contactElem = doc.getRootElement().element("contact");
	//2.得到屬性
	//2.1  得到指定名稱的屬性值
	/*
	String idValue = contactElem.attributeValue("id");
	System.out.println(idValue);
	*/
	
	//2.2 得到指定屬性名稱的屬性對象
	/*Attribute idAttr = contactElem.attribute("id");
	//getName: 屬性名稱    getValue:屬性值
	System.out.println(idAttr.getName() +"=" + idAttr.getValue());*/
	
	//2.3 得到所有屬性對象,返回LIst集合
	/*List<Attribute> list = contactElem.attributes();
	//遍歷屬性
	for (Attribute attr : list) {
		System.out.println(attr.getName()+"="+attr.getValue());
	}*/
	
	//2.4 得到所有屬性對象,返回迭代器
	Iterator<Attribute> it = contactElem.attributeIterator();
	while(it.hasNext()){
		Attribute attr = it.next();
		System.out.println(attr.getName()+"="+attr.getValue());
	}
	
}

/**
 * 獲取文本
 */
@Test
public void test5() throws Exception{
	//1.讀取xml文檔,返回Document對象
	SAXReader reader = new SAXReader();
				
	Document doc = reader.read(new File("./src/contact.xml"));
	
	
	/**
	 * 注意: 空格和換行也是xml的內容
	 */
	String content = doc.getRootElement().getText();
	System.out.println(content);
	
	
	//獲取文本(先獲取標簽,再獲取標簽上的文本)
	Element nameELem = 
		doc.getRootElement().element("contact").element("name");
	//1. 得到文本
	String text = nameELem.getText();
	System.out.println(text);
	
	//2. 得到指定子標簽名的文本內容
	String text2 = 
		doc.getRootElement().element("contact").elementText("phone");
	System.out.println(text2);
	
}


}

第二個練習例子

package gz.itcast.a_dom4j_read;

import java.io.File;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.Text;
import org.dom4j.io.SAXReader;
import org.junit.Test;
/**
 * 練習-完整讀取xml文檔內容
 * @author APPle
 *
 */
public class Demo3 {
@Test
public void test() throws Exception{
	//讀取xml文檔
	SAXReader reader = new SAXReader();
	Document doc = 
			reader.read(new File("./src/contact.xml"));
	
	//讀取根標簽
	Element rootELem = doc.getRootElement();
	
	StringBuffer sb = new StringBuffer();
	
	getChildNodes(rootELem,sb);
	
	System.out.println(sb.toString());
	
}

/**
 * 獲取當前標簽的所有子標簽
 */
private void getChildNodes(Element elem,StringBuffer sb){
	//System.out.println(elem.getName());
	
	//開始標簽ssss
	sb.append("<"+elem.getName());
	
	//得到標簽的屬性列表
	List<Attribute> attrs = elem.attributes();
	if(attrs!=null){
		for (Attribute attr : attrs) {
			//System.out.println(attr.getName()+"="+attr.getValue());
			sb.append(" "+attr.getName()+"=\""+attr.getValue()+"\"");
		}
	}
	sb.append(">");
	
	//得到文本
	//String content = elem.getText();
	//System.out.println(content);
	Iterator<Node> it = elem.nodeIterator();
	while(it.hasNext()){
		Node node = it.next();
		
		//標簽
		if(node instanceof Element){
			Element el = (Element)node;
			getChildNodes(el,sb);
		}
		
		//文本
		if(node instanceof Text){
			Text text = (Text)node;
			sb.append(text.getText());
		}
	}
	
	//結束標簽
	sb.append("</"+elem.getName()+">");		
	
}
}

修改,創建xml

package gz.itcast.a_dom4j_read;

import java.io.File;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.Text;
import org.dom4j.io.SAXReader;
import org.junit.Test;
/**
 * 練習-完整讀取xml文檔內容
 * @author APPle
 *
 */
public class Demo3 {
@Test
public void test() throws Exception{
	//讀取xml文檔
	SAXReader reader = new SAXReader();
	Document doc = 
			reader.read(new File("./src/contact.xml"));
	
	//讀取根標簽
	Element rootELem = doc.getRootElement();
	
	StringBuffer sb = new StringBuffer();
	
	getChildNodes(rootELem,sb);
	
	System.out.println(sb.toString());
	
}

/**
 * 獲取當前標簽的所有子標簽
 */
private void getChildNodes(Element elem,StringBuffer sb){
	//System.out.println(elem.getName());
	
	//開始標簽ssss
	sb.append("<"+elem.getName());
	
	//得到標簽的屬性列表
	List<Attribute> attrs = elem.attributes();
	if(attrs!=null){
		for (Attribute attr : attrs) {
			//System.out.println(attr.getName()+"="+attr.getValue());
			sb.append(" "+attr.getName()+"=\""+attr.getValue()+"\"");
		}
	}
	sb.append(">");
	
	//得到文本
	//String content = elem.getText();
	//System.out.println(content);
	Iterator<Node> it = elem.nodeIterator();
	while(it.hasNext()){
		Node node = it.next();
		
		//標簽
		if(node instanceof Element){
			Element el = (Element)node;
			getChildNodes(el,sb);
		}
		
		//文本
		if(node instanceof Text){
			Text text = (Text)node;
			sb.append(text.getText());
		}
	}
	
	//結束標簽
	sb.append("</"+elem.getName()+">");		
	
}
}

package gz.itcast.a_dom4j_write;

import java.io.File;
import java.io.FileOutputStream;

import org.dom4j.Document;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
/**
 * 討論寫出內容到xml文檔的細節
 * @author APPle
 *
 */
public class Demo2 {

/**
 * @param args
 */
public static void main(String[] args) throws Exception{
	Document doc = new SAXReader().read(new File("./src/contact.xml"));
	//指定文件輸出的位置
	FileOutputStream out = new FileOutputStream("e:/contact.xml");
	/**
	 * 1.指定寫出的格式
	 */
	OutputFormat format = OutputFormat.createCompactFormat(); //緊湊的格式.去除空格換行.項目上線的時候
	//OutputFormat format = OutputFormat.createPrettyPrint(); //漂亮的格式.有空格和換行.開發調試的時候
	/**
	 * 2.指定生成的xml文檔的編碼
	 *    同時影響了xml文檔保存時的編碼  和  xml文檔聲明的encoding的編碼(xml解析時的編碼)
	 *    結論: 使用該方法生成的xml文檔避免中文亂碼問題。
	 */
	format.setEncoding("utf-8");
	
	
	//1.創建寫出對象
	XMLWriter writer = new XMLWriter(out,format);
	
	//2.寫出對象
	writer.write(doc);
	//3.關閉流
	writer.close();
}

}

package gz.itcast.a_dom4j_write;

import java.io.File;
import java.io.FileOutputStream;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.junit.Test;

/**
 * 修改xml內容
 * 增加:文檔,標簽 ,屬性
 * 修改:屬性值,文本
 * 刪除:標簽,屬性
 * @author APPle
 *
 */
public class Demo3 {

/**
 * 增加:文檔,標簽 ,屬性
 */
@Test
public void test1() throws Exception{
	/**
	 * 1.創建文檔
	 */
	Document doc = DocumentHelper.createDocument();
	/**
	 * 2.增加標簽
	 */
	Element rootElem = doc.addElement("contactList");
	//doc.addElement("contactList");
	Element contactElem = rootElem.addElement("contact");
	contactElem.addElement("name");
	/**
	 * 3.增加屬性
	 */
	contactElem.addAttribute("id", "001");
	contactElem.addAttribute("name", "eric");
	
	//把修改后的Document對象寫出到xml文檔中
	FileOutputStream out = new FileOutputStream("e:/contact.xml");
	OutputFormat format = OutputFormat.createPrettyPrint();
	format.setEncoding("utf-8");
	XMLWriter writer = new XMLWriter(out,format);
	writer.write(doc);
	writer.close();
}

/**
 * 修改:屬性值,文本
 * @throws Exception
 */
@Test
public void test2()	throws Exception{
	Document doc = new SAXReader().read(new File("./src/contact.xml"));
	
	/**
	 * 方案一: 修改屬性值   1.得到標簽對象 2.得到屬性對象 3.修改屬性值
	 */
	//1.1  得到標簽對象
	/*
	Element contactElem = doc.getRootElement().element("contact");
	//1.2 得到屬性對象
	Attribute idAttr = contactElem.attribute("id");
	//1.3 修改屬性值
	idAttr.setValue("003");
	*/
	/**
	 * 方案二: 修改屬性值
	 */
	//1.1  得到標簽對象
	/*
	Element contactElem = doc.getRootElement().element("contact");
	//1.2 通過增加同名屬性的方法,修改屬性值
	contactElem.addAttribute("id", "004");
	*/
	
	/**
	 * 修改文本 1.得到標簽對象 2.修改文本
	 */
	Element nameElem = doc.getRootElement().
		element("contact").element("name");
	nameElem.setText("李四");
	
	
	
	FileOutputStream out = new FileOutputStream("e:/contact.xml");
	OutputFormat format = OutputFormat.createPrettyPrint();
	format.setEncoding("utf-8");
	XMLWriter writer = new XMLWriter(out,format);
	writer.write(doc);
	writer.close();
}


/**
 * 刪除:標簽,屬性
 * @throws Exception
 */
@Test
public void test3() throws Exception{
	Document doc = new SAXReader().read(new File("./src/contact.xml"));
	
	/**
	 * 1.刪除標簽     1.1 得到標簽對象  1.2 刪除標簽對象    
	 */
	// 1.1 得到標簽對象
	/*
	Element ageElem = doc.getRootElement().element("contact")
				.element("age");
	
	//1.2 刪除標簽對象
	ageElem.detach();
	//ageElem.getParent().remove(ageElem);
	*/
	/**
	 * 2.刪除屬性   2.1得到屬性對象  2.2 刪除屬性
	 */
	//2.1得到屬性對象
	//得到第二個contact標簽
	Element contactElem = (Element)doc.getRootElement().
		elements().get(1);
	//2.2 得到屬性對象
	Attribute idAttr = contactElem.attribute("id");
	//2.3 刪除屬性
	idAttr.detach();
	//idAttr.getParent().remove(idAttr);
	
	FileOutputStream out = new FileOutputStream("e:/contact.xml");
	OutputFormat format = OutputFormat.createPrettyPrint();
	format.setEncoding("utf-8");
	XMLWriter writer = new XMLWriter(out,format);
	writer.write(doc);
	writer.close();
}
}

xPath技術

package gz.itcast.b_xpath;

import java.io.File;
import java.io.FileOutputStream;

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

/**
 * 第一個xpath程序
 * @author APPle
 *
 */
public class Demo1 {

public static void main(String[] args) throws Exception{
	/**
	 * 需求: 刪除id值為2的學生標簽
	 */
	Document doc = new SAXReader().read(new File("e:/student.xml"));
	
	//1.查詢id為2的學生標簽
	//使用xpath技術
	Element stuElem = (Element)doc.selectSingleNode("//Student[@id='2']");
	//2.刪除標簽
	stuElem.detach();
	
	//3.寫出xml文件
	FileOutputStream out = new FileOutputStream("e:/student.xml");
	OutputFormat format = OutputFormat.createPrettyPrint();
	format.setEncoding("utf-8");
	XMLWriter writer = new XMLWriter(out,format);
	writer.write(doc);
	writer.close();
}

}

package gz.itcast.b_xpath;

import java.io.File;
import java.util.List;

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

/**
 * 學習xPath表達式語法
 * @author APPle
 *
 */
public class Demo2 {
public static void main(String[] args) throws Exception {
	Document doc = new SAXReader().read(new File("./src/contact.xml"));
	
	String xpath = "";
	
	/**
	 * 1.  	/      絕對路徑      表示從xml的根位置開始或子元素(一個層次結構)
	 */
	xpath = "/contactList";
	xpath = "/contactList/contact";
	
	/**
	 * 2. //     相對路徑       表示不分任何層次結構的選擇元素。
	 */
	xpath = "//contact/name";
	xpath = "//name";
	
	/**
	 * 3. *      通配符         表示匹配所有元素
	 */
	xpath = "/contactList/*"; //根標簽contactList下的所有子標簽
	xpath = "/contactList//*";//根標簽contactList下的所有標簽(不分層次結構)
	
	/**
	 * 4. []      條件           表示選擇什么條件下的元素
	 */
	//帶有id屬性的contact標簽
	xpath = "//contact[@id]";
	//第二個的contact標簽
	xpath = "//contact[2]";
	//選擇最后一個contact標簽
	xpath = "//contact[last()]";
	
	/**
	 * 5. @     屬性            表示選擇屬性節點
	 */
	xpath = "//@id"; //選擇id屬性節點對象,返回的是Attribute對象
	xpath = "//contact[not(@id)]";//選擇不包含id屬性的contact標簽節點
	xpath = "//contact[@id='002']";//選擇id屬性值為002的contact標簽
	xpath = "//contact[@id='001' and @name='eric']";//選擇id屬性值為001,且name屬性為eric的contact標簽
	
	/**
	 *6.  text()   表示選擇文本內容
	 */
	//選擇name標簽下的文本內容,返回Text對象
	xpath = "//name/text()";
	xpath = "//contact/name[text()='張三']";//選擇姓名為張三的name標簽
	
	
	List<Node> list = doc.selectNodes(xpath);
	for (Node node : list) {
		System.out.println(node.toString());
	}
}

}

package gz.itcast.b_xpath;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;

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

/**
 * xpath案例: 模擬用戶登錄效果
 * @author APPle
 *
 */
public class Demo3 {

public static void main(String[] args)throws Exception{
	//1.獲取用戶輸入的用戶名和密碼
	BufferedReader br = 
			new BufferedReader(new InputStreamReader(System.in));
	
	System.out.println("請輸入用戶名:");
	String name = br.readLine();
	
	System.out.println("請輸入密碼:");
	String password = br.readLine();
	
	//2.到“數據庫”中查詢是否有對應的用戶
	//對應的用戶:  在user.xml文件中找到一個
	   //name屬性值為‘用戶輸入’,且password屬性值為‘用戶輸入’的user標簽
	Document doc = new SAXReader().read(new File("./src/user.xml"));
	Element userElem = (Element)doc.selectSingleNode("//user[@name='" +name +"' and @password='"+password+"']");
	
	if(userElem!=null){
		//登錄成功
		System.out.println("登錄成功");
	}else{
		//登錄失敗
		System.out.println("登錄失敗");
	}
}

}

package gz.itcast.b_xpath;

import java.io.File;
import java.util.Iterator;
import java.util.List;

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

/**

  • 使用xpath技術讀取一個規范的html文檔
  • @author APPle

*/
public class Demo4 {

public static void main(String[] args) throws Exception{
	Document doc = new SAXReader().read(new File("./src/personList.html"));
	//System.out.println(doc);
	
	//讀取title標簽
	Element titleElem = (Element)doc.selectSingleNode("//title");
	String title = titleElem.getText();
	System.out.println(title);
	
	/**
	 * 練習:讀取聯系人的所有信息
	 * 按照以下格式輸出:
	 * 		 編號:001 姓名:張三 性別:男 年齡:18 地址:xxxx 電話: xxxx
	 *       編號:002 姓名:李四 性別:女 年齡:20 地址:xxxx 電話: xxxx
	 *       ......
	 */
	//1.讀取出所有tbody中的tr標簽
	List<Element> list = (List<Element>)doc.selectNodes("//tbody/tr");
	//2.遍歷
	for (Element elem : list) {
		//編號
		//String id = ((Element)elem.elements().get(0)).getText();
		String id = elem.selectSingleNode("td[1]").getText();
		//姓名
		String name = ((Element)elem.elements().get(1)).getText();
		//性別
		String gender = ((Element)elem.elements().get(2)).getText();
		//年齡
		String age = ((Element)elem.elements().get(3)).getText();
		//地址
		String address = ((Element)elem.elements().get(4)).getText();
		//電話
		String phone = ((Element)elem.elements().get(5)).getText();
		
		System.out.println("編號:"+id+"\t姓名:"+name+"\t性別:"+
							gender+"\t年齡:"+
							age+"\t地址:"+address+
							"\t電話:"+phone);
	}
}

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM