xml文件-1

1 Xml簡單的歷史介紹

1969 gml(通用標記語言) [主要的目的是要在不一樣的機器進行通訊的數據規範]javascript

1985 sgml(標準通用標記語言)css

1993 html (www網)html

Html語言自己是有一些缺陷的java

(1)標記不能自定義node

<html>
<table>
<hsp></hsp>
</table>
</html>

(2)html自己缺乏一些含義程序員

<h1>水滸英雄</h1>
 <table>
 <tr><td>宋江</td><td>及時雨</td></tr>
 </table>

(3)html自己沒有真正的國際化面試

html->xhtml->xml數據庫

1998 xml Xml : extensiable markup language 可擴展標記語言編程

2 爲何要學習xml

(1)需求api

輸入圖片說明

(2)作配置文件

(3)xml文件還能夠描述很複雜的數據關係 好比 家譜… Xml的常見應用

(1)數據傳送通用格式

(2)配置文件

(3)充當小型數據庫

Xml語法 入門案例: 用xml來記錄一個班級信息

<?xml version="1.0" encoding="gb2312"?>
<class>
<stu id="a001">
<name>楊過</name>
<sex>男</sex>
<age>30</age>
</stu>
<stu id="a002">
<name>李莫愁</name>
<sex>女</sex>
<age>20</age>
</stu>
</class>

☞ 編碼問題: ansi 編碼 是 american national standard insititu 美國國家標準協會 , ansi 編碼在不一樣的國家不同的 ansi ->gb2312 anis-gbk big5 日本 ansi->日文操做系統默認的編碼.

3 xml的語法

(1)文檔聲明

<?xml version=」1.0」 encoding=」編碼方式」 standalone=」yes|no」?>

(2)一個xml 文檔中,有且只有一個根元素

元素==標籤==節點

(3)在xml中

<name>xiaoming</name>
不等價與==
<name>
xiaoming
</name>

(4) 屬性值用雙引號(")或單引號(')分隔(若是屬性值中有',用"分隔;有",用'分隔)

特別說明: 若是屬性值有單引號,有雙引號,則須要使用實體: html->  ©

輸入圖片說明

<stu id="a&quot;0&apos;0&apos;1">
<name>楊過</name>
<sex>男</sex>
<age>30</age>
</stu>

(4)CDATA節

有時咱們但願傳遞一些特殊字符, <>@!#$%^&*( 可使用 CDATA節包括

基本用法:

<intro><![CDATA[這個是好$$128qw8o8<Lk;>;akdf0sa98u329408><<K>>>學生]]></intro>

面試題: 問; 如何適用xml 去傳遞小圖片

答: 能夠把文件讀取成一個 byte[] ,而後放到 CDATA節,再傳遞.

(5)處理指令

看一個案例:

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="my.css" type="text/css"?>
<class>
<!--學生信息-->
<stu id="a&quot;0&apos;0&apos;1&lt;" >
<name>楊過</name>
<sex>男</sex>
<age>30</age>
</stu>
<stu id="a002">
<name>李莫愁</name>
<sex>女</sex>
<age>20</age>
</stu>
</class>

xml語法小結: XML聲明語句

<?xml version="1.0" encoding="gb2312"?>

–必須有且僅有一個根元素 –標記大小寫敏感 –屬性值用引號 –標記成對 –空標記關閉 –元素正確嵌套 –名稱中能夠包含字母、數字或者其它字符 –名稱中不能含空格 測 –名稱中不能含冒號(注:冒號留給命名空間使用) 測

4 dtd

基本概念: dtd ( document type definition 文檔類型定義),該文件通常和xml文件配合使用, 主要的用處是約束 xml, 除了 dtd 技術外, 還有一個schema的技術也能夠用於約束xml文件的書寫規範. 如今請看一個問題:

<stu id="a&quot;0&apos;0&apos;1&lt;" >
<name>楊過</name>
<sex>男</sex>
<age>30</age>
<介紹>我是好人</介紹>
<面積>100平</面積>
</stu>

怎麼解決xml過於自由的問題:->dtd xml 和 dtd關係

輸入圖片說明

快速入門案例: 基本語法是:

<!ELEMENT 元素名 類型>

xml:

<?xml version="1.0" encoding="utf-8"?>
<!--引入dtd去約束該xml文件-->
<!DOCTYPE 班級 SYSTEM "myClass2.dtd">
<班級>
	<學生>
		<名字>周星馳</名字>
		<年齡>23</年齡>
		<介紹>學習刻苦</介紹>
	</學生>
	<學生>
		<名字>林青霞</名字>
		 <年齡>32</年齡>
		<介紹>是一個好學生</介紹>
	</學生>
</班級>

myClass2.dtd

<!ELEMENT 班級 (學生+)>
<!ELEMENT 學生 (名字,年齡,介紹)>
<!ELEMENT 名字 (#PCDATA)>
<!ELEMENT 年齡 (#PCDATA)>
<!ELEMENT 介紹 (#PCDATA)>

完成校驗的html

<html>
<head>
<!--本身編寫一個簡單的解析工具,去解析xml dtd 是否配套-->
<script language="javascript">
<!--
	var xmldoc = new ActiveXObject("Microsoft.XMLDOM");
	xmldoc.validateOnParse = "true";//開啓校驗
	xmldoc.load("myClass2.xml");//指定校驗哪一個xml文件
	document.writeln("錯誤信息是:"+xmldoc.parseError.reason+"<br/>");  
	document.writeln("錯誤的行是:"+xmldoc.parseError.line);

//-->
</script>
</head>
<body>
</body>
</html>

dtd的細節 (1)dtd 的分類 內部 dtd 外部 dtd

內部DTD文檔 <!DOCTYPE 根元素 [定義內容]> 外部DTD文檔 <!DOCTYPE 根元素 SYSTEM "DTD文件路徑"> (2)在xml中引入dtd 有兩種方法 1.引入本地 dtd

<!DOCTYPE 根元素 SYSTEM ‘地址’>

2.引入公共的 dtd

<!DOCTYPE 根元素 PUBLIC ‘地址’>

(2)

<!ELEMENT 元素名 類型>

類型: EMPTY, ANY , #PCDATA (3)dtd的修飾符

輸入圖片說明

(4)屬性的細節

基本語法

<!ATTLIST 元素名 屬性名 類型 特色 ..... >

類型有 五種: CDATA 表示能夠放入文本

ID 表示屬性的值,不能重複,同時不要用數字開頭.

IDREF/IDREFS 當一個元素的屬性值,須要去引用另一個ID ,則使用IDREF,若是但願引用多個,則使用

IDREFS,請用空格隔開.

Enumerated 表示屬性的值,只能是例舉出了 好比

<!ATTLIST 學生 地址 CDATA #FIXED "北京" 學號 ID #REQUIRED 大哥 IDREFS #REQUIRED 性別 (男|女) #REQUIRED >

ENTITY

屬性的特色有四種

#REQUIRED 表示必須有

#IMPLIED 表示能夠有

#FIXED 「值」 表示若是有,則必須是什麼

Default 「值」 表示若是不指定,則默認.

實體(ENTITY)

就是實體用於爲一段內容建立一個別名,之後在XML文檔中就可使用別名引用這段內容 了 java : String str=」你好」; 定義str,在別的地方,咱們使用str就能夠訪問到 ‘你好’

輸入圖片說明

(1)分類 引用實體 案例 在 dtd 中定義:

<!ENTITY mycopy "個人公司版權">

說明:最好把定義放在dtd的最後 在xml中使用 &mycopy;

參數實體

基本語法

<!ENTITY % 實體名字 」實體內容」>

引用 %實體名字; 舉例:

<!ELEMENT 班級 (學生*)>
<!ENTITY % myname "名字">
<!ELEMENT 學生 (%myname;,介紹,年齡)>
<!ATTLIST 學生 
   地址 CDATA #FIXED "北京"
   學號 ID #REQUIRED
   大哥 IDREFS #REQUIRED
   性別 (男|女) #REQUIRED
>
<!ELEMENT %myname; (#PCDATA)>
<!ELEMENT 年齡 (#PCDATA)>
<!ELEMENT 介紹  (#PCDATA)>
<!ENTITY mycopy "個人公司版權">

學習dtd的目標:通常公司不多讓程序員本身寫 dtd,要求程序員看的懂dtd,同時能夠根據給出的dtd,寫出對應的xml

一個產品目錄

<!ENTITY AUTHOR "John Doe">
<!ENTITY COMPANY "JD Power Tools, Inc.">
<!ENTITY EMAIL "jd@jd-tools.com">

<!ELEMENT CATALOG (PRODUCT+)>

<!ELEMENT PRODUCT
(SPECIFICATIONS+,OPTIONS?,PRICE+,NOTES?)>
<!ATTLIST PRODUCT
NAME CDATA #IMPLIED
CATEGORY (HandTool|Table|Shop-Professional) "HandTool"
PARTNUM CDATA #IMPLIED
PLANT (Pittsburgh|Milwaukee|Chicago) "Chicago"
INVENTORY (InStock|Backordered|Discontinued) "InStock">

<!ELEMENT SPECIFICATIONS (#PCDATA)>
<!ATTLIST SPECIFICATIONS
WEIGHT CDATA #IMPLIED
POWER CDATA #IMPLIED>

<!ELEMENT OPTIONS (#PCDATA)>
<!ATTLIST OPTIONS
FINISH (Metal|Polished|Matte) "Matte" 
ADAPTER (Included|Optional|NotApplicable) "Included"
CASE (HardShell|Soft|NotApplicable) "HardShell">

<!ELEMENT PRICE (#PCDATA)>
<!ATTLIST PRICE
MSRP CDATA #IMPLIED
WHOLESALE CDATA #IMPLIED
STREET CDATA #IMPLIED
SHIPPING CDATA #IMPLIED>

<!ELEMENT NOTES (#PCDATA)>
xml...
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE CATALOG SYSTEM 'product.dtd'>
<CATALOG>
<PRODUCT NAME="康師傅礦泉水" CATEGORY="HandTool" PARTNUM="abc" PLANT="Milwaukee"   INVENTORY="Backordered">
<SPECIFICATIONS WEIGHT="800" POWER="600" >這裏是細節</SPECIFICATIONS>
<PRICE>110</PRICE>
</PRODUCT>
</CATALOG>

5 xml編程

爲何要學習xml編程(就是對xml文件進程crud操做) 1.xml做爲數據傳遞,須要解析 2.xml做爲配置文件,須要讀取. 3.xml做爲小型數據庫.crud

在j2ee 技術中,主要是學習 java 對xml 操做 ,和 js 對 xml操做

目前有兩種模式 dom 是 w3c 推出的標準 sax 是社區的標準

咱們在授課中,主要講三套api dom sax dom4j

6 java 解析xml 【dom技術】 看原理:

輸入圖片說明

咱們講一個快速入門案例:

<?xml version="1.0" ?>
<班級>
	<學生>
		<名字>周星馳</名字>
		<年齡>23</年齡>
		<介紹>學習刻苦</介紹>
	</學生>
	<學生>
		<名字>林青霞</名字>
		 <年齡>32</年齡>
		<介紹>是一個好學生</介紹>
	</學生>
</班級>

代碼:(使用dom 去遍歷xml文件和指定獲取某個節點)

//具體的查詢某個學生的信息(顯示第一個學生的全部信息)
	//請考慮如何獲取某個元素的屬性值,(取出)
	public static void read(Document doc){
		
		NodeList nl=doc.getElementsByTagName("學生");
		//取出第一個學生
		Element stu=(Element) nl.item(0);
		System.out.println("學生的性別是"+stu.getAttribute("sex"));
		Element name=(Element) stu.getElementsByTagName("年齡").item(0);
		System.out.println(name.getTextContent());
		//System.out.println("發現"+nl.getLength());
		
	}
	//遍歷該xml文件
	public static void list(Node node){
		if(node.getNodeType()==node.ELEMENT_NODE){
			System.out.println("名字"+node.getNodeName());
		}
		//取出node的子節點
		NodeList nodeList=node.getChildNodes();
		for(int i=0;i<nodeList.getLength();i++){
			//再去顯示
			Node n=nodeList.item(i);
			list(n);
		}
		
	}

下面的是使用dom 取添加一個新的元素:

//添加一個學生到xml文件中
	public static void add(Document doc) throws Exception{
		
		//建立一個新的學生節點
		Element newStu=doc.createElement("學生");
		//添加一個屬性值
		newStu.setAttribute("sex", "男");
		Element newStu_name=doc.createElement("名字");
		newStu_name.setTextContent("小明2");
		Element newStu_age=doc.createElement("年齡");
		newStu_age.setTextContent("34");
		Element newStu_intro=doc.createElement("介紹");
		newStu_intro.setTextContent("這是一個好孩子");
		newStu.appendChild(newStu_name);
		newStu.appendChild(newStu_age);
		newStu.appendChild(newStu_intro);
		
		//把新的學生節點添加到根元素
		doc.getDocumentElement().appendChild(newStu);
		
		//獲得TransformerFactory
		TransformerFactory tff=TransformerFactory.newInstance();
		//經過TransformerFactory 獲得一個轉換器
		Transformer tf=tff.newTransformer();
		tf.transform(new DOMSource(doc), new StreamResult("src/classes.xml"));
		
		
	}

刪除某個元素或者是某個屬性

//刪除一個元素(刪除小明2學生)
	public static void del(Document doc) throws Exception{
		
		//首先要找到這個學生
		//Node node= doc.getElementsByTagName("學生").item(0);
		//node.getParentNode().removeChild(node);
		//刪除學生的sex屬性
		Element node= (Element) doc.getElementsByTagName("學生").item(0);
		node.removeAttribute("sex");
		
		//更新xml
		//獲得TransformerFactory
		TransformerFactory tff=TransformerFactory.newInstance();
		//經過TransformerFactory 獲得一個轉換器
		Transformer tf=tff.newTransformer();
		tf.transform(new DOMSource(doc), new StreamResult("src/classes.xml"));
	}

//更新操做

//更新元素(把第一個學生的名改爲 宋江)
	public static void upd(Document doc) throws Exception{
	
			//找到
			Element node=(Element) doc.getElementsByTagName("學生").item(0);
			Element node_name=(Element) node.getElementsByTagName("名字").item(0);
			node_name.setTextContent("宋江");
			//node_name.setAttribute("sex", arg1)
			//更新xml
			//獲得TransformerFactory
			TransformerFactory tff=TransformerFactory.newInstance();
			//經過TransformerFactory 獲得一個轉換器
			Transformer tf=tff.newTransformer();
			tf.transform(new DOMSource(doc), new StreamResult("src/classes.xml"));
	}

7 sax技術

單說面試題: 說請下下面的代碼會出現什麼問題? byte bytes[]=new byte[102410241000]; bytes[0]=0; System.out.println(bytes[0]); 實際考察你會不會 指定 jvm啓動的 內存大小: 答: jvm機啓動時有一個默認大小 jdk5.0 64m, 若是咱們但願改變jvm機啓動的內存大小能夠經過修改 –Xmx?m 來處理 ?能夠本身指定

1.爲何會出現sax技術 由於dom技術,會把整個xml文件加載到內存中,這樣若是 xml過大,則可能會出現內存溢出. 3.sax技術能夠在不加載所有 xml 文件時,就能夠解析xml文檔,看一個原理圖:

輸入圖片說明

sax技術的案例:

package com.sax.test;
import javax.xml.parsers.*;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class Sax1 {
	//使用sax技術去解析xml文件.myclasses2.xml
	public static void main(String[] args) throws Exception, SAXException {
		// TODO Auto-generated method stub
		//1.建立SaxParserFactory
		SAXParserFactory spf=SAXParserFactory.newInstance();
		//2.建立SaxParser 解析器
		SAXParser saxParser=spf.newSAXParser();
		//3 把xml文件和事件處理對象關聯
		saxParser.parse("src/myclasses2.xml",new MyDefaultHandler2() );
	}
}
//請思考,如何只顯示學生的名字和年齡
class MyDefaultHandler2 extends DefaultHandler{
	private boolean isName=false;
	private boolean isAge=false;
	[@Override](https://my.oschina.net/u/1162528)
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		// TODO Auto-generated method stub
		String con=new String(ch,start,length);
		if(!con.trim().equals("")&&(isName||isAge)){
			System.out.println(con);
		}
		isName=false;
		isAge=false;
		//super.characters(ch, start, length);
	}
	[@Override](https://my.oschina.net/u/1162528)
	public void endDocument() throws SAXException {
		// TODO Auto-generated method stub
		super.endDocument();
	}
	[@Override](https://my.oschina.net/u/1162528)
	public void endElement(String uri, String localName, String name)
			throws SAXException {
		// TODO Auto-generated method stub
		super.endElement(uri, localName, name);
	}
	[@Override](https://my.oschina.net/u/1162528)
	public void startDocument() throws SAXException {
		// TODO Auto-generated method stub
		super.startDocument();
	}
	@Override
	public void startElement(String uri, String localName, String name,
			Attributes attributes) throws SAXException {
		// TODO Auto-generated method stub
		if(name.equals("名字")){
			this.isName=true;
		}else if(name.equals("年齡")){
			this.isAge=true;
		}
	}
}
//定義事件處理類
class MyDefaultHandler1 extends DefaultHandler{
	//發現文檔開始
	@Override
	public void startDocument() throws SAXException {
		// TODO Auto-generated method stub
		System.out.println("startDocument()");
		super.startDocument();
	}
	//發現xml文件中的一個元素
	@Override
	public void startElement(String uri, String localName, String name,
			Attributes attributes) throws SAXException {
		// TODO Auto-generated method stub
		System.out.println("元素名稱="+name);	
	}
	//發現xml文件中的文本
	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		String con=new String(ch,start,length);
		//顯示文本內容:
		if(!con.trim().equals("")){
			System.out.println(new String(ch,start,length));
		}
	}
	//發現xml文件中一個元素介紹</xx>
	@Override
	public void endElement(String uri, String localName, String name)
			throws SAXException {
		// TODO Auto-generated method stub
		super.endElement(uri, localName, name);
	}
	//發現文檔結束
	@Override
	public void endDocument() throws SAXException {
		// TODO Auto-generated method stub
		System.out.println("endDocument()");
		super.endDocument();
	}
}

對sax說明:

  1. sax主要用於對xml文件解析(讀取),不能去修改,刪除,添加元素
  2. sax 是推機制,把發現的內容告訴程序員(函數),程序員能夠本身決定如何處理

8 dom4j(jdom)

1.爲何有dom4j dom 缺點 : 比較耗費內存 sax缺點: 只能對xml進行讀取,可是不能去 修改,添加,刪除. dom4j :既能夠提升效率,同時也能夠進行crud 特別說明: 由於dom4j不是sun公司的產品,因此咱們開發dom4j須要引入jar包.

(1)快速入門 如何適用dom4j技術對xml文件進程(crud)操做

9 xpath的必要性

爲了咱們根據方便的訪問的某個節點,咱們可使用xpath技術,當使用xpath後,就能夠很是方便的讀取到指定節點,xpath每每是結合dom4j一併使用. 說明:若是要使用xpath 則須要引入一個新的包:

原理圖:

輸入圖片說明

特別說明:

//@id 選擇全部的id屬性

<AAA> 
      <BBB id = "b1"/> 
      <BBB id = "b2"/> 
      <BBB name = "bbb"/> 
      <BBB/> 
 </AAA>

若是咱們經過 //@id 取回的節點類型是 Attribue,不是Element 用法: //3.可使用xpath隨心讀取 List e=document.selectNodes("//@id");//返回多個元素 System.out.println(((Attribute)e.get(1)).getText());

注意:xpath 是能夠任意組合: 好比:

<?xml version="1.0" encoding="utf-8"?>
<AAA> 
          <BBB id = "b1">
          <CCC>
          <KKK>k2</KKK>
          </CCC>
          <CCC>
          <KKK>k1</KKK>
          </CCC>
          </BBB> 
          <BBB id = "b2"/> 
          <BBB name = "bbb"/> 
          <BBB/> 
     </AAA>

要找到 <KKK>k2</KKK> xpath 應該這樣寫 : /AAA/BBB[1]/CCC[1]/KKK

案例:

package com.dom4jxpath.test;

import java.util.List;

import org.dom4j.*;
import org.dom4j.io.*;

public class Test1 {

	//dom4j 配合 xpath案例
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		//1.獲得SAXReader 解析器
		SAXReader saxReader =new SAXReader();
		//2.指定去解析哪一個文件
		Document document = saxReader.read("src/com/dom4jxpath/test/test.xml");
		
		//3.可使用xpath隨心讀取
		List e=document.selectNodes("/AAA/BBB[1]/CCC[1]/KKK");//返回多個元素 document.selectSingleNode
		System.out.println(((Element)e.get(0)).getText());
		//System.out.println(((Attribute)e.get(1)).getText());
		
		
		//若是咱們肯定只有一個Node,元素則可使用selectSingleNode
		//Element e2=(Element) document.selectSingleNode("/AAA/BBB[last()]");
		//System.out.println(e2.getText());
	}

}

做用: 用dom4j+xpath 完成學生課程維護系統.

相關文章
相關標籤/搜索