天天看點

XML語言

                第一天XML語言

1、什麼是XML?為什麼學習XML?

可擴充标記語言,XML技術是w3c組織釋出的,目前推薦遵循的是W3C組織于2000釋出的XML1.0規範

在現實中大量存在有關系的資料

2、XML技術用于解決什麼問題?

XML語言出現的根本目标在于描述上圖那種,在現實生活中經常出現的有關系的資料

在XML語言中,它允許使用者自定義标簽,一個标簽用于描述一段資料,一個标簽可以分為開始标簽和結束标簽,在開始标簽和結束标簽之間,又可以使用其它标簽描述其他資料,以此來實作資料關系的描述

3、XML常見應用

(1)XML技術除用了儲存有關系的資料外,它還經常用做軟體配置檔案,以描述程式子產品之間的關系

(2)在一個軟體系統中,為提高系統的靈活性,它所啟動的子產品通常由其配置檔案決定

例如一個軟體在啟動時,他需要啟動A、B兩個子產品,而A、B這兩個子產品在啟動時,又分别需要A1、A2和B1、B2子產品的支援,為了準确描述這種關系,此時使用XML檔案最為合适不過

(3)在Java開發中,傳統的配置檔案是*.properties屬性檔案(key=value),而XML表示的資料更為豐富。

(4)XML技術除用于描述有關系的資料外,還經常用作軟體配置檔案,以描述程式子產品之間的關系。(如後面将要學習到的Struts2、Spring和Hibernate都是基于XML作為配置檔案的)

(5)在一個軟體系統中,通過XML配置檔案可以提高系統的靈活性。即程式的行為是通過XML檔案來配置的,而不是寫死。

4、XML文法

一個XML檔案分為如下幾個部分内容:(文檔聲明、元素、屬性、注釋、CDATA區、特殊字元、處理指令)

5、XML文法——文檔聲明

在編寫XML文檔時,需要先使用文檔聲明,聲明XML文檔的類型

(1)最簡單的聲明文法:<?Xml version=“1.0”?>

(2)用encoding屬性說明文檔的字元編碼:<?Xml version=“1.0” encoding=“gb2312”?>

(3)用standalone屬性說明文檔是否獨立:<?Xml version=”1.0” encoding=”GB2312” standalone=”yes”?>

6、元素

XML元素指XML檔案中出現的标簽,一個标簽分為開始标簽和結束标簽,一個标簽有如下幾種書寫形式

例如:包含标簽體:<a> hello</a>

      不含标簽體:<a></a>簡寫成:</a>

一個标簽中也可以嵌套若幹子标簽。但所有标簽必須合理的嵌套,絕對不允許交叉嵌套。

格式良好的XML文檔必須有且僅有一個根标簽,其他标簽都是這個根标簽的子孫标簽

對于XML标簽中出現的所有空格和換行,XML解析程式都會當作标簽内容進行處理,例如下面兩段内容的意義是不一樣的

第一段:<百度>www.baidu.com</百度>

第二段:

<百度>

www.baidu.com

</百度>

由于在XML中,空格和換行都作為原始内容被處理,是以,在編寫XML檔案時,使用換行和縮進等方式來讓原檔案中的内容清晰可讀的良好書寫習慣可能要被迫改變

7、元素命名規範

一個XML元素可以包含字母、數字以及其他一些可見字元,但必須遵守下面的規範

(1)區分大小寫,例如<P>和<p>是兩個不同的标記

(2)不能以數字或“_”(下劃線)開頭

(3)不能以xml(或XML、Xml等)開頭

(4)不能包含空格

(5)名稱中間不能包含冒号(:)

8、屬性

(1)一個标簽可以有多個屬性,每個屬性都有它自己的名稱和取值,

例如:<input name=”text”>

(2)屬性值一定要用雙引号(“”)或者單引号(‘’)引起來

(3)定義屬性必須遵循與标簽相同的命名規範

(4)多學一招:在XML技術中,标簽屬性所代表的資訊也可以被改成子元素的形式來描述

例如:<input>

            <name>text</name>

      </input>

9、注釋

Xml檔案中的注釋采用:<!--注釋-->格式

注意:XML聲明之前不能有注釋,注釋不能嵌套,不能出現在第一行

10、CDATA區(Character Data)

在編寫XML時,有些内容可能不想讓解析引擎解析執行,而是當原始内容處理。遇到此種情況,可以把這些内容放到CDATA區裡。對于CDATA區域内的内容,XML解析程式不會處理,而是直接原封不動的輸出

作用:把标簽當作普通文本内容

文法:<![CDATA[内容]]>

11、轉義字元

對于一些單個字元,若想顯示其原始樣式,也可以使用轉義的形式予以處理

(1)&——&       (ampersand縮寫)

(2)<——<          (less than縮寫)

(3)>——>          (grant than縮寫)

(4)“——"         (quotation縮寫)

(5)‘——&apos         (apostrophe縮寫)

補充:在XML中加入CSS

<?xml-stylesheet type=”text/css”?>

12、處理指令(了解一下即可)

處理指令,簡稱PI(processing Instruction)處理指令用來指揮解析引擎如何解析XML文檔内容

例如:在XML文檔中可以使用xml-stylesheet指令,通知XML解析引擎,應用css檔案顯示xml文檔内容

<?xml-stylesheet type=”text/css” href=”1.css”>

處理指令必須以“<?”作為開頭,以“?>”作為結尾,XML聲明語句就是最常見的一種處理指令

13、XML限制概述

什麼是XML限制?

在XML技術裡,可以編寫一個文檔來限制一個XML文檔的書寫規範,這稱之為XML限制

常用的限制技術:

(1)XML DTD

(2)XML Schema(最常用)

(3)XDR

(4)SOX

兩個概念:

(1) 格式良好的XML,遵循XML文法的XML

(2) 有效的XML ,遵循限制的XML

14、DTD限制快速入門

DTD(Document Type Definition),全稱為文檔類型定義

檔案清單: book.xml

<?xml version=”1.0”?>

<!DOCTYPE 書架 SYSTEM “book dtd”>    ——注意這個

<書架>

<書>

    <書名>Java教育訓練</書名>

    <作者>張孝祥</作者>

    <售價>30.00</售價>

</書>

<書>

      <書名>JavaScript網頁開發</書名>

      <作者>張孝祥</作者>

      <售價>28.00</售價>

</書>

</書架>

檔案清單:book.dtd

<!ELEMENT 書架(書+)>                       //多本書

<!ELEMENT 書架 書(書名、作者、售價)>       //書裡可以包含書名、作者、售價

<!ELEMENT 書名(#PCDATA)>                 //可以解析的字元資料區

<!ELEMENT 作者(#PCDATA)>

<!ELEMENT 售價(#PCDATA)>

DTD檔案應使用UTF-8或Unicode

15、程式設計校驗XML文檔正确性

IE5以上的浏覽器内置了XML解析工具Microsoft.XMLDOM,開發人員可以編寫JavaScript代碼,利用這個解析工具裝載xml檔案,并對xml檔案進行dtd校驗

(1)建立xml文檔解析器對象

Var xmldoc=new ActiveXObject(“Microsofy XMLDOM”);

(2)開啟xml校驗

xmldoc.validateOnParse=”true”;

(3)裝載xml文檔

xmldoc.load(“book.xml”);

(4)擷取錯誤資訊

xmldoc.parseError.reason;

xmldoc.parseError.line;

16、編寫DTD限制的兩種方式

DTD限制既可以作為一個單獨的檔案編寫,也可以在XML檔案内編寫

17、在xml檔案内編寫DTD

<?xml version=”1.0” encoding=”UTF-8” standalone=yes””>

<!DOCTYPE 書架[

<!ELEMENT 書架(書+)>

<!ELEMENT 書架 書(書名、作者、售價)>

<!ELEMENT 書名(#PCDATA)>

<!ELEMENT 作者(#PCDATA)>

<!ELEMENT 售價(#PCDATA)>

]>

<書架>

<書>

    <書名>Java教育訓練</書名>

    <作者>張孝祥</作者>

    <售價>30.00</售價>

</書>

<書>

      <書名>JavaScript網頁開發</書名>

      <作者>張孝祥</作者>

      <售價>28.00</售價>

</書>

</書架>

18、引用DTD限制

XML檔案使用DOCTYPE聲明語句來指明它所遵循的DTD檔案,DOCTYPE聲明語句有兩種形式:

(1)當引用檔案在本地時,采用如下格式:

<!DOCTYPE 文檔根節點 SYSTEM “DTD檔案的URL”>

例如:<!DOCTYPE 書架 SYSTEM “book.dtd”>

(2)當引用檔案是一個公共檔案時,采用如下方式:

<!DOCTYPE 文檔根節點 PUBLIC “DTD名稱” “DTD檔案的URL”>

例如:<!DOCTYPE web-app PUBLIC “-//Sun MicroSystems.Inc//DTD Web Application 2.3//EN” “http://java.sun.com/dtd/web-app_2_3.dtd”>

19、DTD限制文法的細節

元素定義、屬性定義、實體定義

20、DTD文法——元素定義

在DTD文檔中使用ELEMENT聲明一個XML元素,文法格式如下:

<!ELEMENT 元素名稱 元素類型>

元素類型可以是元素内容或類型。

如為元素内容,則需要使用括号()括起來,如:

<!ELEMENT 書架(書名,作者,售價)>   ——順序不能改變

<!ELEMENT 書名(#PCDATA)>

如為元素類型,則直接書寫,DTD規範定義了如下幾種類型:

EMPTY:用于定義空元素,例如<br/><hr/>

ANY:表示元素内容為任意類型

元素内容中可以使用如下方式,描述内容的組成關系

(1)用逗号分隔,表示内容出現的順序必須與聲明時一緻。

<!ELEMENT MYFILE (TITLE ,AUTHOR,EMALL)>

(2)用|分隔,表示任其選一,即多個隻能出現一個

<!ELEMENT MYFILE(TITLE|AYTHOR|EMAIL)>

(3)在元素内容中也可以使用+、*、?等符号表示元素出現的次數

+:一次或多次(書+)

?:0次或1次(書?)

*:0次或多次(書*)

(4)也可以使用圓括号()批量設定,例如

<!ELEMENT> MYFILE((TITLE*,AUTHOR?,EMAIL)*|COMMENT)

21、屬性定義——attribute

Xml文檔中的标簽屬性通過ATTLIST為其設定屬性

文法格式:

<ATTLIST 元素名

屬性名1 屬性值類型 設定說明 

屬性名1 屬性值類型 設定說明 

.......

>

屬性聲明舉例:

<!ATTLIST 商品

類别 CDATA #REQUIRED  ——要求的

顔色 CDATA #IMPLTED  ——暗示的,可以設定也可以不設定

>

對應XML檔案:

<商品 類别=“服裝” 顔色=“黃色”>...</商品>

<商品 類别=“服裝”>...</商品>

22、屬性定義

設定說明:

(1)#REQUIRED:必須設定該屬性

(2)#IMPLIED:可以設定也可以不設定

(3)#FIXED:說明該屬性的取值固定為一個值,在XML檔案中不能為該屬性設定其他的值,但需要為該屬性提供這個值

(4)直接使用預設值:在XML中可以設定該值也可以不設定該屬性值,若沒使用則使用預設值

舉例:

<!ATTLIST 頁面作者

姓名 CDATA #IMPLIED

年齡 CDATA #IMPLIED

聯系資訊 CDATA #REQUIRED>

網站職務 CDATA #FIXED “頁面作者”

個人愛好 CDATA “上網”

>

23、常用屬性值類型

CDATA:表示屬性值為普通文本字元串

ENUMERATED(枚舉)

ID (身份證)

ENTITY(實體)

24、屬性值類型——ENUMERATED

屬性的類型可以使一組取值的清單,在XML檔案中設定的屬性值隻能是這個清單中的某個值(枚舉)

<?xml version=”1.0” encoding=”GB2312” standalone=”yes” >

<!DOCTYPE 購物籃[                    ——根标簽是購物籃

<!ELEMENT 肉 EMPTY>               ——肉裡面不能嵌套标簽

<!ATTLIST 肉 品種(雞肉|牛肉|豬肉|魚肉)“雞肉”>

]>        

<購物籃>

<肉 品種=“魚肉”/>

<肉 品種=“牛肉”/>

<肉/>

</購物籃>

25、屬性值類型——ID

表示屬性設定的值為一個唯一的值

ID屬性的值隻能由字母,下劃線開始,不能出現空白字元

<?xml version=”1.0” encoding=”GB2312”?>

<!DOCTYPE 聯系人清單[

<!ELEMENT 聯系人清單 ANY>

<!ELEMENT 聯系人(姓名,EMAIL)>

<!ELEMENT 姓名(#PCDATA)>

<!ELEMENT EMAIL(#PCDATA)>

<!ATTLIST 聯系人 編号 ID #REQUIRED>

]>

<聯系人清單>

<聯系人 編号=“1”>

    <姓名>張三</姓名>

    <EMAIL>[email protected]</EMAIL>

</聯系人>

<聯系人 編号=“2”>

    <姓名>李四</姓名>

    <EMAIL>[email protected]</EMAIL>

</聯系人>

<聯系人清單>

26、實體定義

(1)實體用于為一切内容建立一個别名,以後在XML文檔中就可以使用别名引用這段内容了

(2)在DTD定義中一條<!ENTITY...>語句用于定義一個實體

(3)實體可以分為兩種類型:引用實體和參數實體

27、實體定義——引用實體

(1)引用實體主要在XML文檔中被應用

(2)文法格式:<!ENTITY 實體名稱 “實體内容”>:直接轉變成實體内容

(3)引用方式:&實體名稱

(4)舉例:<!ENTITY copyright “I am a poogrammer”>

......

©right

28、實體定義——參數實體

參數實體被DTD檔案自身使用

文法格式:<!ENTITY  %  實體名稱 實體内容>

引用方式:%實體名稱;

舉例1:<!ENTITY %TAG_NAME “姓名|EMAIL|電話|位址”>

        <!ELEMENT 個人資訊 (%TAG_NAME;|生日)>

        <!ELEMENT 客戶資訊 (%TAG_NAME;|公司名)>

舉例2:<!ENTITY % common.attributes “id ID #IMPLIED account CDATA #REQUIRED”>

...

<!ATTLIST purchaseOrder %common.attributes;>

<!ATTLIST item  %common.attributes;>

29、XML解析技術概述

XML解析方式分為兩種:dom和sax

Dom:(Document Object Model,即文檔對象模型)是W3C組織推薦的解析XML的一種方式

SAX:(Simple API for XML)不是官方标準,但它是XML社群事實上的标準,幾乎所有的XML解析器都支援它

XML解析開發包:Jaxp(sun)、Jdom、dom4j

DOM和SAX解析方法的差別:

(1)dom解析的優點是對文檔crud比較友善,缺點是占用記憶體比較大

(2)Sax解析優點是占用記憶體小,解析速度快,缺點是隻适合做文檔的讀取,不适合做文檔的curd

30、調整jvm大小

參考資料:

 Sun HotSpot 1.4.1使用分代收集器,它把堆分為三個主要的域:新域、舊域以及永久域。Jvm生成的所有新對象放在新域中。一旦對象經曆了一定數量的垃圾收集循環後,便獲得使用期并進入舊域。在永久域中jvm則存儲class和method對象。就配置而言,永久域是一個獨立域并且不認為是堆的一部分。

  下面介紹如何控制這些域的大小。可使用-Xms和-Xmx 控制整個堆的原始大小或最大值。

  下面的指令是把初始大小設定為128M:

  java –Xms128m

  –Xmx256m為控制新域的大小,可使用-XX:NewRatio設定新域在堆中所占的比例。

  下面的指令把整個堆設定成128m,新域比率設定成3,即新域與舊域比例為1:3,新域為堆的1/4或32M:

java –Xms128m –Xmx128m

–XX:NewRatio =3可使用-XX:NewSize和-XX:MaxNewsize設定新域的初始值和最大值。

  下面的指令把新域的初始值和最大值設定成64m:

java –Xms256m –Xmx256m –Xmn64m

  永久域預設大小為4m。運作程式時,jvm會調整永久域的大小以滿足需要。每次調整時,jvm會對堆進行一次完全的垃圾收集。

  使用-XX:MaxPerSize标志來增加永久域搭大小。在WebLogic Server應用程式加載較多類時,經常需要增加永久域的最大值。當jvm加載類時,永久域中的對象急劇增加,進而使jvm不斷調整永久域大小。為了避免調整,可使用-XX:PerSize标志設定初始值。

  下面把永久域初始值設定成32m,最大值設定成64m。

java -Xms512m -Xmx512m -Xmn128m -XX:PermSize=32m -XX:MaxPermSize=64m

   預設狀态下,HotSpot在新域中使用複制收集器。該域一般分為三個部分。第一部分為Eden,用于生成新的對象。另兩部分稱為救助空間,當Eden 充滿時,收集器停止應用程式,把所有可到達對象複制到目前的from救助空間,一旦目前的from救助空間充滿,收集器則把可到達對象複制到目前的to救 助空間。From和to救助空間互換角色。維持活動的對象将在救助空間不斷複制,直到它們獲得使用期并轉入舊域。使用-XX:SurvivorRatio 可控制新域子空間的大小。

  同NewRation一樣,SurvivorRation規定某救助域與Eden空間的比值。比如,以下指令把新域設定成64m,Eden占32m,每個救助域各占16m:

java -Xms256m -Xmx256m -Xmn64m -XX:SurvivorRation =2

   如前所述,預設狀态下HotSpot對新域使用複制收集器,對舊域使用标記-清除-壓縮收集器。在新域中使用複制收集器有很多意義,因為應用程式生成的 大部分對象是短壽命的。理想狀态下,所有過渡對象在移出Eden空間時将被收集。如果能夠這樣的話,并且移出Eden空間的對象是長壽命的,那麼理論上可 以立即把它們移進舊域,避免在救助空間反複複制。但是,應用程式不能适合這種理想狀态,因為它們有一小部分中長壽命的對象。最好是保持這些中長壽命的對象 并放在新域中,因為複制小部分的對象總比壓縮舊域廉價。為控制新域中對象的複制,可用-XX:TargetSurvivorRatio控制救助空間的比例 (該值是設定救助空間的使用比例。如救助空間位1M,該值50表示可用500K)。該值是一個百分比,預設值是50。當較大的堆棧使用較低的sruvivorratio時,應增加該值到80至90,以更好利用救助空間。用-XX:maxtenuring threshold可控制上限。

  為放置所有的複制全部發生以及希望對象從eden擴充到舊域,可以把MaxTenuring Threshold設定成0。設定完成後,實際上就不再使用救助空間了,是以應把SurvivorRatio設成最大值以最大化Eden空間,設定如下:

java … -XX:MaxTenuringThreshold=0 –XX:SurvivorRatio=50000 …

31、JAXP

(1)JAXP:(Java API for XML Processing)開發包是JavaSE的一部分,它由以下幾個包及其子包組成:

(2)org.w3c.dom:提供DOM方式解析XML的标準接口

(3)org.xml.sax:提供SAX方式解析XML的标準接口

(4)javax.xml:提供了解析XML文檔的類

(5)javax.xml.parsers包中,定義了幾個工廠類。我們可以通過調用這些工廠類,得到對XML文檔進行解析的DOM和SAX解析器對象:

DocumentBuilderFactory   SAXParserFactory

32、使用JAXP進行DOM解析

(1)調用 DocumentBuilderFactory.newInstance() 方法得到建立 DOM 解析器的工廠。

(2)調用工廠對象的 newDocumentBuilder方法得到 DOM 解析器對象。

(3)調用 DOM 解析器對象的 parse() 方法解析 XML 文檔,得到代表整個文檔的 Document 對象,進而可以利用DOM特性對整個XML文檔進行操作了。

33、DOM程式設計

DOM模型(document object model)

DOM解析器在解析XML文檔時,會把文檔中的所有元素,按照其出現的層次關系,解析成一個個Node對象(節點)。

在dom中,節點之間關系如下:

位于一個節點之上的節點是該節點的父節點(parent)

一個節點之下的節點是該節點的子節點(children) 

同一層次,具有相同父節點的節點是兄弟節點(sibling) 

一個節點的下一個層次的節點集合是節點後代(descendant)

父、祖父節點及所有位于節點上面的,都是節點的祖先(ancestor) 

節點類型

34、Node對象

(1)Node對象提供了一系列常量來代表結點的類型,當開發人員獲得某個Node類型後,就可以把Node節點轉換成相應的節點對象(Node的子類對象),以便于調用其特有的方法。(檢視API文檔) 

(2)Node對象提供了相應的方法去獲得它的父結點或子結點。程式設計人員通過這些方法就可以讀取整個XML文檔的内容、或添加、修改、删除XML文檔的内容了。

35、更新XML文檔

javax.xml.transform包中的Transformer類用于把代表XML檔案的Document對象轉換為某種格式後進行輸出,例如把xml檔案應用樣式表後轉成一個html文檔。利用這個對象,當然也可以把Document對象又重新寫入到一個XML檔案中。

Transformer類通過transform方法完成轉換操作,該方法接收一個源和一個目的地。我們可以通過:

javax.xml.transform.dom.DOMSource類來關聯要轉換的document對象, 

用javax.xml.transform.stream.StreamResult 對象來表示資料的目的地。

 Transformer對象通過TransformerFactory獲得。

36、DOM 解析練習.

1.讀取節點的文本内容

2.讀取屬性值

3.添加節點

4.删除節點

5.更新節點

6.列印所有元素節點的名稱.

package Exercise;

import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import javax.xml.parsers.ParserConfigurationException;

import javax.xml.transform.Transformer;

import javax.xml.transform.TransformerConfigurationException;

import javax.xml.transform.TransformerException;

import javax.xml.transform.TransformerFactory;

import javax.xml.transform.TransformerFactoryConfigurationError;

import javax.xml.transform.dom.DOMSource;

import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;

import org.w3c.dom.Element;

import org.w3c.dom.Node;

import org.w3c.dom.NodeList;

import org.xml.sax.SAXException;

public class dom1 

{

 // (1)、首先拿到 一個 documentbuilderfactory 對象.

 //(2)、 通過 factory 對象拿到 一個 documentbuilder對象.

//(3)、通過 builder的 parse 方法獲得一個 document 對象.

public static void main(String[]args) throws ParserConfigurationException, SAXException, IOException, TransformerException

{

     //readAttribute();//讀取屬性

 //readContext();//讀取内容

//addElement();//添加節點

//deleteElement();//删除節點

//updateElement();//更新節點

treeWalk();

}

private static void readAttribute() throws ParserConfigurationException,

SAXException, IOException {

//1、讀取屬性值

 // (1)、首先拿到 一個 documentbuilderfactory 對象.

DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();

 //(2)、 通過 factory 對象拿到 一個 documentbuilder對象.

DocumentBuilder db=dbf.newDocumentBuilder();

//(3)、通過 builder的 parse 方法獲得一個 document 對象.

Document doc = db.parse("src/book.xml");

//(4)、通過document對象擷取各個節點

Node node = doc.getElementsByTagName("書").item(0);

Element e=(Element)node;

System.out.println(e.getNodeName()+"——"+e.getAttribute("出版社"));//擷取屬性名

}

private static void readContext() throws ParserConfigurationException,

SAXException, IOException {

    //2、讀取節點文本内容

    // (1)、首先拿到 一個 documentbuilderfactory 對象.

    DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();

    //(2)、 通過 factory 對象拿到 一個 documentbuilder對象.

    DocumentBuilder db = dbf.newDocumentBuilder();

    //(3)、通過 builder的 parse 方法獲得一個 document 對象.

    Document doc=db.parse("src/book.xml");

    //(4)擷取Node節點

    Node node = doc.getElementsByTagName("書").item(0);

    String value=node.getTextContent();//擷取節點内部的内容

    //System.out.print(value);

    }

private static void addElement() throws ParserConfigurationException,

SAXException, IOException, TransformerFactoryConfigurationError,

TransformerConfigurationException, TransformerException {

// 3.添加節點 :  <售價>59.00</售價>

// (1)、首先拿到 一個 documentbuilderfactory 對象.

DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();

//(2)、 通過 factory 對象拿到 一個 documentbuilder對象.

DocumentBuilder db = dbf.newDocumentBuilder();

//(3)、通過 builder的 parse 方法獲得一個 document 對象.

Document doc = db.parse("src/book.xml");

//(4)、通過document對象建立一個節點

Element newele = doc.createElement("售價");

//newele.setNodeValue("59222.00");

newele.setTextContent("69.00");

//(5)、把新添加的節點連接配接到記憶體中指定的父節點上

Node node = doc.getElementsByTagName("書").item(0);

node.appendChild(newele);

//(6)、将記憶體中的xml文檔寫入到實際檔案中,這裡需要用到transformer

//首先拿到一個transformer的工廠

TransformerFactory tf=TransformerFactory.newInstance();

//(7)、通過transformer工廠擷取一個transformer對象

Transformer tt=tf.newTransformer();

//(8)、開始轉換

tt.transform(new DOMSource(doc), new StreamResult("src/book.xml"));

}

private static void deleteElement() throws ParserConfigurationException, SAXException, IOException, TransformerException

{

    //4、删除節點

// (1)、首先拿到 一個 documentbuilderfactory 對象.

   DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();

   //(2)、 通過 factory 對象拿到 一個 documentbuilder對象.

   DocumentBuilder db = dbf.newDocumentBuilder();

   //(3)、通過 builder的 parse 方法獲得一個 document 對象.

   Document doc = db.parse("src/book.xml");

   //(4)、找到要删除的節點

   Node node = doc.getElementsByTagName("售價").item(1);

   System.out.println(node.getTextContent());

   //(5)、把他從記憶體中删除掉

    node.getParentNode().removeChild(node);

  //(6)、将記憶體中的xml文檔寫入到實際檔案中,這裡需要用到transformer

   //首先拿到一個transformer的工廠

    TransformerFactory tff=TransformerFactory.newInstance();

  //(7)、通過transformer工廠擷取一個transformer對象

    Transformer tf = tff.newTransformer();

  //(8)、開始轉換

    tf.transform(new DOMSource(doc), new StreamResult("src/book.xml"));

}

    public static void updateElement() throws SAXException, IOException, ParserConfigurationException, TransformerException

    {

     //5、更新節點

     // (1)、首先拿到 一個 documentbuilderfactory 對象.

     DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();

      //(2)、 通過 factory 對象拿到 一個 documentbuilder對象.

     DocumentBuilder db = dbf.newDocumentBuilder();

     //(3)、通過 builder的 parse 方法獲得一個 document 對象.

     Document doc = db.parse("src/book.xml");

     //(4)、通過document對象擷取需要更新的節點

     Node node = doc.getElementsByTagName("售價").item(1);

     //(5)、修改該節點裡面的内容

     node.setTextContent("88.00");

     //(6)、将記憶體中的xml文檔寫入到實際檔案中,這裡需要用到transformer

   //首先拿到一個transformer的工廠

      TransformerFactory tff=TransformerFactory.newInstance();

      //(7)、通過transformer工廠擷取一個transformer對象

     Transformer tf=tff.newTransformer(); 

      //(8)、開始轉換

     tf.transform(new DOMSource(doc), new StreamResult("src/book.xml") );

    }

private static void treeWalk() throws ParserConfigurationException, SAXException, IOException

{

// (1)、首先拿到 一個 documentbuilderfactory 對象.

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

 //(2)、 通過 factory 對象拿到 一個 documentbuilder對象.

DocumentBuilder builder = factory.newDocumentBuilder();

//(3)、通過 builder的 parse 方法獲得一個 document 對象.

Document document = builder.parse("src/book.xml");

listNode(document);

}

private static void listNode(Node node) {

// TODO Auto-generated method stub

//(4)、判斷是否是元素節點,是的話列印出來

if(node.getNodeType() == Node.ELEMENT_NODE){

System.out.println(node.getNodeName());

}

//(5)、周遊該節點的子節點

NodeList nl = node.getChildNodes();

for (int i = 0; i < nl.getLength(); i++) {

Node node1 = nl.item(i);

//(6)、遞歸的思想繼續調用這個函數列印

listNode(node1);

}

}

}

37、SAX解析  

(1)在使用 DOM 解析 XML 文檔時,需要讀取整個 XML 文檔,在記憶體中構架代表整個 DOM 樹的Doucment對象,進而再對XML文檔進行操作。此種情況下,如果 XML 文檔特别大,就會消耗計算機的大量記憶體,并且容易導緻記憶體溢出。   

(2)SAX解析允許在讀取文檔的時候,即對文檔進行處理,而不必等到整個文檔裝載完才對文檔進行操作。

(3)SAX采用事件處理的方式解析XML檔案,利用 SAX 解析 XML 文檔,涉及兩個部分:解析器和事件處理器:

(4)解析器可以使用JAXP的API建立,建立出SAX解析器後,就可以指定解析器去解析某個XML文檔。???

(5)解析器采用SAX方式在解析某個XML文檔時,它隻要解析到XML文檔的一個組成部分,都會去調用事件處理器的一個方法,解析器在調用事件處理器的方法時,會把目前解析到的xml檔案内容作為方法的參數傳遞給事件處理器。

(6)事件處理器由程式員編寫,程式員通過事件處理器中方法的參數,就可以很輕松地得到sax解析器解析到的資料,進而可以決定如何對資料進行處理。

38、SAX方式解析XML文檔

(1)使用SAXParserFactory建立SAX解析工廠

     SAXParserFactory spf = SAXParserFactory.newInstance();

(2)通過SAX解析工廠得到解析器對象

     SAXParser sp = spf.newSAXParser();

(3)通過解析器對象得到一個XML的讀取器

     XMLReader xmlReader = sp.getXMLReader();

(4)設定讀取器的事件處理器

     xmlReader.setContentHandler(new BookParserHandler());

(5)解析xml檔案

     xmlReader.parse("book.xml");

package Exercise;

import java.io.IOException;

import javax.xml.parsers.ParserConfigurationException;

import javax.xml.parsers.SAXParser;

import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;

import org.xml.sax.ContentHandler;

import org.xml.sax.Locator;

import org.xml.sax.SAXException;

import org.xml.sax.XMLReader;

import org.xml.sax.helpers.DefaultHandler;

public class Sax1 {

public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException 

{

        //運用SAX解析XML

//(1)使用SAXParserFactory建立SAX解析工廠

        SAXParserFactory spf=SAXParserFactory.newInstance();

        //(2)通過SAX解析工廠得到解析器對象

        SAXParser sp = spf.newSAXParser();

        //(3)通過解析器對象得到一個XML的讀取器

        XMLReader xr = sp.getXMLReader();

        //(4)設定讀取器的事件處理器

        xr.setContentHandler(new MyHandle());

        //(5) 解析 xml文檔

        xr.parse("src/book.xml");

}

}

class MyHandle extends DefaultHandler

{

     boolean flag=true;

@Override

public void startDocument() throws SAXException {

// TODO Auto-generated method stub

System.out.println("解析到文檔的開始");

}

@Override

public void endDocument() throws SAXException {

// TODO Auto-generated method stub

//System.out.println("解析到文檔的結束");

}

@Override

public void startElement(String uri, String localName, String qName,

Attributes atts) throws SAXException {

// TODO Auto-generated method stub

        for(int i=0;i<atts.getLength();i++)

        {

         String tagName=atts.getQName(i);

         String value=atts.getValue(tagName);

         System.out.println(tagName+"——"+value);

        }

        if(qName.equals("售價"))

        {

         flag=false;

         System.out.print(qName);

        }

//System.out.println("解析到文檔的開始标簽"+qName);

}

@Override

public void endElement(String uri, String localName, String qName)

throws SAXException {

// TODO Auto-generated method stub

//System.out.println("解析到文檔的結束标簽"+qName);

}

public void characters(char[] ch, int start,int length)

     throws SAXException

     {

super.characters(ch, start, length);

//System.out.println(new String(ch,start,length));

if(flag==false)

{

System.out.println(new String(ch,start,length));

flag=true;

}

     }

}

39、DOM4J解析XML文檔

(1)Dom4j是一個簡單、靈活的開放源代碼的庫。Dom4j是由早期開發JDOM的人分離出來而後獨立開發的。與JDOM不同的是,dom4j使用接口和抽象基類,雖然Dom4j的API相對要複雜一些,但它提供了比JDOM更好的靈活性。 

(2)Dom4j是一個非常優秀的Java XML API,具有性能優異、功能強大和極易使用的特點。現在很多軟體采用的Dom4j,例如Hibernate,包括sun公司自己的JAXM也用了Dom4j。

使用Dom4j開發,需下載下傳dom4j相應的jar檔案。

40、Document對象

DOM4j中,獲得Document對象的方式有三種:

1.讀取XML檔案,獲得document對象            

                   SAXReader reader = new SAXReader();

              Document   document = reader.read(new File("input.xml"));

2.解析XML形式的文本,得到document對象.

                   String text = "<members></members>";

              Document document = DocumentHelper.parseText(text);

3.主動建立document對象.

                  Document document = DocumentHelper.createDocument();

             //建立根節點

                  Element root = document.addElement("members");

41、節點對象

1.擷取文檔的根節點.

      Element root = document.getRootElement();

2.取得某個節點的子節點.

Element element=node.element(“書名");

3.取得節點的文字

      String text=node.getText();

4.取得某節點下所有名為“member”的子節點,并進行周遊.

 List nodes = rootElm.elements("member");

  for (Iterator it = nodes.iterator(); it.hasNext();) {

     Element elm = (Element) it.next();

    // do something

 }

5.對某節點下的所有子節點進行周遊.

    for(Iterator it=root.elementIterator();it.hasNext();){

       Element element = (Element) it.next();

       // do something

    }

6.在某節點下添加子節點.

Element ageElm = newMemberElm.addElement("age");

7.設定節點文字.

 element.setText("29");

8.删除某節點.

//childElm是待删除的節點,parentElm是其父節點

    parentElm.remove(childElm);

9.添加一個CDATA節點.

Element contentElm = infoElm.addElement("content");

contentElm.addCDATA(diary.getContent());

42、節點對象屬性 

1.取得某節點下的某屬性

    Element root=document.getRootElement();    

    //屬性名name

         Attribute attribute=root.attribute("size");

2.取得屬性的文字

    String text=attribute.getText();

 3.删除某屬性

 Attribute attribute=root.attribute("size");

 root.remove(attribute);

3.周遊某節點的所有屬性

   Element root=document.getRootElement();    

   for(Iterator it=root.attributeIterator();it.hasNext();){

         Attribute attribute = (Attribute) it.next();

         String text=attribute.getText();

         System.out.println(text);

    }

4.設定某節點的屬性和文字.

   newMemberElm.addAttribute("name", "sitinspring");

5.設定屬性的文字

   Attribute attribute=root.attribute("name");

   attribute.setText("sitinspring");

43、将文檔寫入XML檔案

1.文檔中全為英文,不設定編碼,直接寫入的形式.

  XMLWriter writer = new XMLWriter(new  FileWriter("output.xml"));

  writer.write(document);

  writer.close();

2.文檔中含有中文,設定編碼格式寫入的形式.

OutputFormat format = OutputFormat.createPrettyPrint();

// 指定XML編碼                   

     format.setEncoding("GBK");       

XMLWriter writer = new XMLWriter(new FileOutputStream("output.xml"),format);

writer.write(document);

writer.close();

44、字元串與XML的轉換 

1.将字元串轉化為XML

2. String text = "<members> <member>sitinspring</member></members>";

Document document = DocumentHelper.parseText(text);

2.将文檔或節點的XML轉化為字元串.

     SAXReader reader = new SAXReader();

Document   document = reader.read(new File("input.xml"));            

Element root=document.getRootElement();    

String docXmlText=document.asXML();

String rootXmlText=root.asXML();

Element memberElm=root.element("member");

String memberXmlText=memberElm.asXML();

45、pull 解析器

(1)pull 解析器是一個第三方的開源api,其解析原理與sax 解析原理很相像,都是采用事件驅動的方式. 

(2)不同點: pull 解析器在每次讀取到一段資料之後,需要程式員手動的調用其next() 方法,将目前解析到的這一行的"指針"移到下一行.

(3)在目前的android 平台中解析xml 檔案都是采用pull解析器,是谷歌力推的xml解析器。pull 解析器是一個開源的java項目,既可以用于android,也可以用于JavaEE。

(4)在android源碼根目錄的libcore目錄下存放的是pull 解析器相關的所有類庫.

package cn.itheima.pull;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

import java.util.ArrayList;

import java.util.List;

import org.xmlpull.v1.XmlPullParser;

import org.xmlpull.v1.XmlPullParserException;

import org.xmlpull.v1.XmlPullParserFactory;

import cn.itheima.domain.Book;

public class Demo2 {

public static void main(String[] args) throws Exception {

List<Book> books = getBooks();

for (Book book : books) {

System.out.println(book);

}

}

private static List<Book> getBooks() throws XmlPullParserException,

Exception {

List<Book> list = new ArrayList<Book>();

XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); 

XmlPullParser parser = factory.newPullParser();

parser.setInput(new FileInputStream("src/book.xml"), "UTF-8");

int eventType = parser.getEventType();

Book book = null;

while(eventType!=XmlPullParser.END_DOCUMENT){

switch (eventType) {

case XmlPullParser.START_TAG:

String name = parser.getName();

if("書".equals(name)){

String publisher = parser.getAttributeValue(0);

book = new Book();

book.setPublisher(publisher);

}

if("書名".equals(name)){

String bookName = parser.nextText();

book.setBookName(bookName);

}

if("作者".equals(name)){

String author = parser.nextText();

book.setAuthor(author);

}

if("售價".equals(name)){

String price = parser.nextText();

book.setPrice(price);

}

break;

case XmlPullParser.END_TAG:

if("書".equals(parser.getName())){

list.add(book);

book = null;

}

break;

default:

break;

}

eventType = parser.next();

}

return list;

}

}

46、XML Schema

(1)XML Schema 也是一種用于定義和描述 XML 文檔結構與内容的模式語言,其出現是為了克服 DTD 的局限性

(2)XML Schema VS DTD

XML Schema符合XML文法結構。 

DOM、SAX等XML API很容易解析出XML Schema文檔中的内容。 

XML Schema對名稱空間支援得非常好。 

XML Schema比XML DTD支援更多的資料類型,并支援使用者自定義新的資料類型。 

XML Schema定義限制的能力非常強大,可以對XML執行個體文檔作出細緻的語義限制。

XML Schema不能像DTD一樣定義實體,比DTD更複雜,但Xml Schema現在已是w3c組織的标準,它正逐漸取代DTD。 

(3)XML Schema 檔案自身就是一個XML檔案,但它的擴充名通常為.xsd。

(4)一個XML Schema文檔通常稱之為模式文檔(限制文檔),遵循這個文檔書寫的xml檔案稱之為執行個體文檔。

(5)和XML檔案一樣,一個XML Schema文檔也必須有一個根結點,但這個根結點的名稱為Schema。

(6)編寫了一個XML Schema限制文檔後,通常需要把這個檔案中聲明的元素綁定到一個URI位址上,在XML Schema技術中有一個專業術語來描述這個過程,即把XML Schema文檔聲明的元素綁定到一個名稱空間上,以後XML檔案就可以通過這個URI(即名稱空間)來告訴解析引擎,xml文檔中編寫的元素來自哪裡,被誰限制。

<?xml version="1.0" encoding="UTF-8" ?> 

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"

  targetNamespace="http://www.itcast.cn"

  elementFormDefault="qualified">

<xs:element name='書架' >

<xs:complexType>

<xs:sequence maxOccurs='unbounded' >

<xs:element name='書' >

<xs:complexType>

<xs:sequence>

<xs:element name='書名' type='xs:string' />

<xs:element name='作者' type='xs:string' />

<xs:element name='售價' type='xs:string' />

</xs:sequence>

</xs:complexType>

</xs:element>

</xs:sequence>

</xs:complexType>

</xs:element>

</xs:schema>

=====================================================================

<?xml version="1.0" encoding="UTF-8"?>

<itcast:書架 xmlns:itcast="http://www.itcast.cn"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation=“http://www.itcast.cn book.xsd">

<itcast:書>

<itcast:書名>JavaScript網頁開發</itcast:書名>

<itcast:作者>張孝祥</itcast:作者>

<itcast:售價>28.00元</itcast:售價>

</itcast:書>

</itcast:書架>

47、名稱空間的概念 

(1)在XML Schema中,每個限制模式文檔都可以被賦以一個唯一的名稱空間,名稱空間用一個唯一的URI(Uniform Resource Identifier,統一資源辨別符)表示。 在Xml檔案中書寫标簽時,可以通過名稱空間聲明(xmlns),來聲明目前編寫的标簽來自哪個Schema限制文檔。如:

<itcast:書架 xmlns:itcast=“http://www.itcast.cn”>

<itcast:書>……</itcast:書>

</itcast:書架>

 此處使用itcast來指向聲明的名稱,以便于後面對名稱空間的引用。

(2)注意:名稱空間的名字文法容易讓人混淆,盡管以 http:// 開始,那個 URL 并不指向一個包含模式定義的檔案。事實上,這個 URL:http://www.itcast.cn根本沒有指向任何檔案,隻是一個配置設定的名字。

(3)為了在一個XML文檔中聲明它所遵循的Schema檔案的具體位置,通常需要在Xml文檔中的根結點中使用schemaLocation屬性來指定,例如:

<itcast:書架 xmlns:itcast="http://www.itcast.cn"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation=“http://www.itcast.cn book.xsd">

schemaLocation此屬性有兩個值。第一個值是需要使用的命名空間。第二個值是供命名空間使用的 XML schema 的位置,兩者之間用空格分隔。

(4)注意,在使用schemaLocation屬性時,也需要指定該屬性來自哪裡。

48、使用預設名稱空間 

基本格式:

xmlns="URI"  

舉例:

<書架 xmlns="http://www.it315.org/xmlbook/schema"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation=“http://www.itcast.cn book.xsd">

<書>

<書名>JavaScript網頁開發</書名>

<作者>張孝祥</作者>

<售價>28.00元</售價>

</書>

<書架>

使用名稱空間引入多個XML Schema文檔 

檔案清單:xmlbook.xml

<?xml version="1.0" encoding="UTF-8"?>

<書架 xmlns="http://www.it315.org/xmlbook/schema" 

xmlns:demo="http://www.it315.org/demo/schema"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.it315.org/xmlbook/schema  http://www.it315.org/xmlbook.xsd 

http://www.it315.org/demo/schema http://www.it315.org/demo.xsd">

<書>

<書名>JavaScript網頁開發</書名>

<作者>張孝祥</作者>

<售價 demo:币種=”人民币”>28.00元</售價>

</書>

</書架>

不使用名稱空間引入XML Schema文檔 

檔案清單:xmlbook.xml

<?xml version="1.0" encoding="UTF-8"?>

<書架 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:noNamespaceSchemaLocation="xmlbook.xsd">

<書>

<書名>JavaScript網頁開發</書名>

<作者>張孝祥</作者>

<售價>28.00元</售價>

</書>

</書架>

在XML Schema文檔中聲明名稱空間

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"

       targetNamespace="http://www. itcast.cn"

       elementFormDefault="qualified">

<xs:schema>

targetNamespace元素用于指定schema文檔中聲明的元素屬于哪個名稱空間。

elementFormDefault元素用于指定,該schema文檔中聲明的根元素及其所有子元素都屬于targetNamespace所指定的名稱空間