XML可擴展標記語言

一、XML可擴展標記語言

1、概念:

XML推出初衷是爲了替換HTML,標籤名可以直接定義,不能用數字開頭 不能使用純數字 區分大小寫,後用做配置文件 封裝數據

因爲xml具有良好的格式,所以用途非常廣泛,比如持久化存儲數據 數據交換 數據配置

xml和html的區別

1)html的標籤是固定的,不能擴展。xml的標籤是不固定的,可擴展的。

2)html側重於顯示的信息。xml側重於標識信息的結構。 

3)html是不區分大小寫的。xml是區分大小寫的。xml的語法比html更嚴謹。

2、組成部分

文檔聲明:<?xml version="1.0" encoding="utf-8"?>

必須頂行 頂格寫

根標籤:有且僅有一個根標籤

其他標籤:有開始標籤 一定要有結束標籤

標籤屬性:一個標籤可以有多個屬性,每個屬性都有它自己的名稱和取值,例如:<Student name="text">

註解:<!-- --> //Comment註釋對象

標籤裏的內容 egg張三:<name>張三</name>

XML標籤中出現的所有空格和換行,XML解析程序都會當作標籤內容進行處理

3、解析思想

DOM解析思想:Document Object Model 文檔對象模型(dom4j解析)

將文檔一次性 加載進內存 然後將文檔各個組成部分抽取爲對象

優點: 能夠對文檔進行增刪改查

缺點:耗內存 適用於PC端

SAX解析思想:基於事件 逐行解析,一次讀取一行,釋放一行(sax解析、pull解析)

優點 :不佔內存  適用於移動端

缺點:只能查 不能增刪改

二、dom4j解析

讀取xml文件步驟:

1、導入DOM4J jar包

2、創建解析器對象

SAXReader reader = new SAXReader();

Document doc = reader.read(new FileInputStream("xml文件名.xml"));

3、獲取根標籤對象

Element rootElement = doc.getRootElement();

1) rootElement.node(第幾個節點);//獲取單個節點對象

獲取根標籤下的子節點(不能獲取孫子節點),空白地方也算一個子節點對象

rootElement.nodeIterator();//獲取多個節點對象

2) rootElement.element("標籤名");//獲取第一個子標籤對象

rootElement.elements();//獲取所有的子標籤對象

rootElement.elementIterator();//通過迭代器的方式獲取所有的子標籤對象

4、獲取標籤屬性對象

Element element = rootElement.element("標籤名");

Attribute attribute = element.attribute(第幾個屬性/"屬性名");

attribute.getName();//獲取屬性的鍵

attribute.getValue();//獲取屬性的值

//element.attributes();獲取所有的屬性對象 

//element.attributeIterator();通過迭代器的方式獲取所有的屬性對象

//element.attributeValue(第幾個屬性/"屬性名");直接獲取屬性對象的值

5、獲取標籤內文本

List<Element> list = element.elements();

for(Element ele:list){

String text = ele.getText();//獲取文本內容

System.out.println(text);

}

用代碼寫xml文件步驟:

導入DOM4J jar包

//通過文檔幫助類create doc
		Document doc = DocumentHelper.createDocument();
		
		//添加一個根標籤
		Element rootEle = doc.addElement("students");
		//添加一個子標籤
		Element ele = rootEle.addElement("student");
		//給student標籤添加一個屬性
		ele.addAttribute("id", "9527");
		//給student添加一個名字和學號標籤及內容
		Element element1 = ele.addElement("sname");
		element1.addText("張三");
		Element element2 = ele.addElement("sid");
		element2.addText("007");
		
		//把內存中doc 寫到硬盤上
		OutputFormat format1 = OutputFormat.createCompactFormat();
		OutputFormat format2 = OutputFormat.createPrettyPrint(); //漂亮的格式
		// 在開發階段 利於我們調試 可以使用漂亮的格式
		// 項目開發好之後上線,我們要調整成緊湊格式 減小xml文件的體積
		XMLWriter writer = new XMLWriter(new FileOutputStream("mydoc.xml"), format2);
		writer.write(doc);
		writer.close();


用代碼修改xml文件步驟:

//找到你想修改的節點

1)修改屬性的值

attribute.setValue("新屬性值");

2)修改文本

element.setText("新文本");

3)刪除標籤、屬性

element.detach();

attribute.detach();

// 重新寫入到硬盤覆蓋掉原文件

XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("xml文件名.xml"));

xmlWriter.write(doc);

xmlWriter.close();

附:XPath:主要是用於xml快速獲取所需的節點對象

1、導入Dom4j 的jar包 和支持xPath技術的jar包

2、使用xpath方法:

List<Node> list = rootElement.selectNodes("xpath表達式");   查詢多個節點對象

Node nade = rootElement.selectSingleNode("xpath表達式");  查詢一個節點對象

3、xpath表達式

/      絕對路徑     選擇該標籤下子標籤

//     相對路徑     該標籤下所有標籤,表示不分任何層次結構的選擇元素。

*      通配符       表示匹配所有元素

[]      條件        表示選擇什麼條件下的元素 

@       屬性        表示選擇屬性節點,定位一個屬性名

and     關係        表示條件的與關係(等價於&&)

not()   取反

text()  文本        表示選擇文本內容

egg:String path = "//user[@id='2']/name"; //選出所有user標籤中id="2"的user標籤下的name標籤

三、sax解析

sax解析有兩個部分,解析器和事件處理器

解析器就是XMLReader接口,負責讀取XML文檔,和向事件處理器發送事件(也是事件源)

事件處理器ContentHandler接口,負責對發送的事件響應和進行XML文檔處理

爲了簡化開發提供了ContentHandler的實現類DefaultHandler類

//事件處理器

public class MyContentHandler extends DefaultHandler{
			//文檔解析開始時調用,該方法只會調用一次
			@Override
			public void startDocument() throws SAXException {
				super.startDocument();
			}
			//標籤開始時調用
			@Override
			public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
				 //uri:xml文檔的命名空間(用不到)
				 //localName:標籤的名字(用不到)
				 //qName:帶命名空間的標籤的名字(使用標籤名用這個)
				 // attributes:標籤的屬性集
				super.startElement(uri, localName, qName, attributes);
			}
			//解析標籤的內容的時候調用
			@Override
			public void characters(char[] ch, int start, int length) throws SAXException {
				//ch:當前讀取到的TextNode(文本節點)的字節數組
				//start:字節開始的位置,爲0則讀取全部
				//length:當前TextNode的長度 
				super.characters(ch, start, length);
			}
			//標籤結束時調用
			@Override
			public void endElement(String uri, String localName, String qName) throws SAXException {
				super.endElement(uri, localName, qName);
			}
			//文檔解析結束後調用,該方法只會調用一次
			@Override
			public void endDocument() throws SAXException {
				super.endDocument();
			}
		}


//解析器

//獲取解析器工廠對象,從而獲取解析器對象

SAXParserFactory factory = SAXParserFactory.newInstance();

SAXParser parser = factory.newSAXParser();

//使用指定的DefaultHandler解析指定文件

parser.parse(new File("文件名.xml"), new MyContentHandler());

四、pull解析

Xmlpull比Sax更簡明,而且不需要掃描完整個流

步驟:

//導入kxml2-2.3.0.jar    xmlpull_1_1_3_4c.jar第三方jar包

//獲取解析器工廠對象,從而獲取解析器對象
	XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
	XmlPullParser parser = factory.newPullParser();
	//關聯xml文件	
	parser.setInput(new FileInputStream("文件名.xml"), "utf-8");
	//獲取事件類型
	int type = parser.getEventType();
		//XmlPullParser.START_DOCUMENT;	文檔開始事件0
		//XmlPullParser.END_DOCUMENT;	文檔結束事件1
		//XmlPullParser.START_TAG; 	開始標籤事件2
		//XmlPullParser.END_TAG; 	結束標籤事件3
		//XmlPullParser.TEXT;	代表文本4
	while (type != XmlPullParser.END_DOCUMENT) {
		String tagName = parser.getName();
		switch (type) {
			case XmlPullParser.START_TAG:
				if("標籤名".equals(tagName)){
					//操作(javabean)
				}else if("標籤名".equals(tagName)){
					//...
				}
				break;
			case XmlPullParser.END_TAG:
				if("標籤名".equals(tagName)){
					//操作(add)
				}
				break;
		}
		//讓指針跳到下一行,重新給type賦值,不然就會死循環
		type = parser.next()
	}
	//把內存中的數據序列化到硬盤上去永久保存
	//獲取解析器工廠對象,從而獲取序列化器
	XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
	XmlSerializer serializer = factory.newSerializer();
	//設置輸出流關聯xml文件
	serializer.setOutput(new FileOutputStream("文件名.xml"), "utf-8");
	//寫入文檔聲明(文檔開始)
	serializer.startDocument("utf-8", true);//參數二:文檔是否獨立
	//寫入開始根標籤
	serializer.startTag(null, "students");//參數1 命名空間一般給null 參數2 標籤名稱
	//寫入根標籤的子標籤student開始標籤
	serializer.startTag(null, "student");
	serializer.attribute(null, "id", "id值");//寫入屬性
	//寫入student標籤的子標籤name開始標籤
	serializer.startTag(null, "name");
	//寫入name標籤內文本
	serializer.text("文本內容");
	//寫入name結束標籤
	serializer.endTag(null, "name");
	//同樣方法寫student標籤的子標籤age
	//寫入student結束標籤
	serializer.endTag(null, "student");
	//同樣方法寫多個student,一般使用循環
	//寫入結束根標籤
	serializer.endTag(null, "students");
	//文檔結束
	serializer.endDocument();



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章