posts - 37, comments - 8, trackbacks - 0, articles - 0

          jsp程序設計:DOM+SAX操作xml

          Posted on 2008-10-24 07:02 夢與橋 閱讀(737) 評論(0)  編輯  收藏 所屬分類: jsp程序設計
          1、操作XML文件的開源軟件包括DOM、SAX、JDOM等,程序員需要熟悉并掌握這些常用的接口的使用,能夠通過這些接口編寫java語句來實現對XML文件的處理。
          2、DTD主要有下列幾方面的作用:
          1)可以驗證XML文件數據的有效性。
          2)可以為某類XML文件提供統一的格式和相同的結構。
          3)可以保證在一定的范圍內,XML文件數據的交流和共享。
          4)應用程序設計人員根據DTD就能夠知道對應XML文件的邏輯結構,從而編寫出相應的處理應用程序。
          3、在DTD中引進Namespaces這個概念是為了解決命名沖突問題,設置url并不是說真的要到那個網址去讀取,僅僅作為一種區別的標志而已。
          4、DOM
          1)DOM的類
          目前主流的解析器有:JAXP(Java Api for XML Processing)、Xerces(Apache)、XML4J(IBM)和xalan等,主流的解析器都支持SAX和DOM,支持JDOM的解析器目前只有SUN公司發布的jdom包。DOM即文件對象模型。在應用程序中,基于DOM的XML分析器將一個XML文件轉換成了一個對象模型的集合(通常被稱為DOM樹),應用程序可以通過對該對象模型的操作,實現對XML文件中數據的操作。
              §Document類,描述了整個XML的文件語法結構,它包含了一系列Node類形成的樹形結構。程序員可以先掃描XML源文件,得到相應的Document對象,遍歷這顆樹來得到XML文件的所有內容,這是對XML文件操作的起點。
              §Node對象,Node類是DOM結構中最為基本的類,經描述了文件樹中的一個抽象的節點。它包含類型為Element、Attr、Text和其他類的特征。Node對象引用其成員的變量來操作XML文件。
              §NodeList對象,代表了一個包含了一個或者多個Node的列表。
              §Element對象,Element類描述XML文件中的標志元素,繼承于Node,也是Node的最主要的子對象。標志中要以包含屬性,因而Element對象中有存取其屬性的方法,而任何Node中定義的方法,Element都繼承下來。
              §Attribute對象,它代表了某個標志的屬性。繼承Node,但因為Attr實際上包含在Element中,不能被看作Element的子對。在DOM中Attributer并不是DOM樹的一個節點,所以Node中的getparentNode()、getpreviousSibling()和getnextSibling()返回的都將是null。即,Attribute是Element類的一部分,并不作為DOM樹中單獨的一個節點出現。
          DOM類在DOM中都是用接口語言IDL定義的,因而,DOM可以映射到任何面向對象的語言,只要它實現了DOM所定義的接口就可以了。許多公司和廠家都提供了符合DOM規范的DOM接口和程序包。以微軟的DOM接口為例:
          2)DOM讀取XML文件,通常用到以下5個基本步驟:
              ?建立一個解析器工廠。
          DocumentBuilderFactory factory=DocumentBuilderFactory.newInstace();
              利用工廠獲得一個具體的解析器對象。
          DocumentBuilder builder=factory.newDocumentBuilder();
              ƒ利用DocumentBuilder的parse()方法接受一個XML文件名作為輸入參數,返回一個Document對象。Document對象代表了一個XML文件的樹模型。
          Document doc=builder.parse("file.xml");
              使用Document對象的getElementsByTagName()方法,我們可以得到一個NodeList對象,它是XML文件中的標簽元素列表,可以使用NodeList對象的item()方法來得到列表中的每一個Node對象。
          NodeList nl=doc.getElementsByTagName("person");
          Element node
          =(Element)nl.item(i);
              通過Node對象的getNodeValue()方法提取某個標簽內的內容。
          node.getElementsByTagName("NAME").item(0).getFirstChild().getNodeValue();
          3)DOM讀取XML文件實例:本實例有兩個文件(book.xml與bookDisplay.jsp)
          book.xml的代碼如下:
          <?xml version="1.0" encoding="gb2312"?>
          <books>
          <book>
          <name>J2EE編程技術</name>
          <author>郝玉龍等</author>
          <price cointype="¥">27.00元</price>
          <publish>清華大學出版社</publish>
          <date>
          <day>15</day>
          <month>3</month>
          <year>2005</year>
          </date>
          </book>
          <book>
          <name>JSP大學實用教程</name>
          <author>耿祥義等</author>
          <price cointype="¥">24.00元</price>
          <publish>電子工業出版社</publish>
          <date>
          <day>21</day>
          <month>9</month>
          <year>2007</year>
          </date>
          </book>
          <book>
          <name>JAVA2游戲編程</name>
          <author>Thomas Petchel</author>
          <price cointype="$">10.00元</price>
          <publish>清華大學出版社</publish>
          <date>
          <day>1</day>
          <month>8</month>
          <year>2005</year>
          </date>
          </book>
          <book>
          <name>JSP應用開發</name>
          <author>鄧子云等</author>
          <price cointype="¥">49.00元</price>
          <publish>機械工業出版社</publish>
          <date>
          <day>11</day>
          <month>12</month>
          <year>2007年</year>
          </date>
          </book>
          </books>
          bookDisplay.jsp的代碼如下:
          <%@ page contentType="text/html;charset=gb2312"%>
          <%@ page import="javax.xml.parsers.*,org.w3c.dom.*"%>
          <html>
          <head>
          <title> DOM讀取book.xml</title>
          </head>
          <body>
          <table border=1 align="center">
              
          <!--輸出表頭-->
              
          <tr bgcolor="yellow">
                  
          <td>書名</td>
                  
          <td>作者</td>
                  
          <td>定價</td>
                  
          <td>出版社</td>
                  
          <td>出版日期</td>        
              
          </tr>
          <%
              DocumentBuilderFactory factory
          =DocumentBuilderFactory.newInstance();
              DocumentBuilder builder
          =factory.newDocumentBuilder();
                  //此處用的是絕對路徑,相對路徑不太好使。
              Document doc
          =builder.parse("C:/Program Files/Apache Software Foundation/Tomcat 6.0/webapps/readXml/book.xml");
              doc.normalize();
              NodeList books
          =doc.getElementsByTagName("book");
              
          for(int i=0;i<books.getLength();i++){
                  Element book
          =(Element)books.item(i);
                  out.print(
          "<tr>");
                  out.print(
          "<td>"+book.getElementsByTagName("name").item(0).getFirstChild().getNodeValue()+"</td>");
                  out.print(
          "<td>"+book.getElementsByTagName("author").item(0).getFirstChild().getNodeValue()+"</td>");
                  out.print(
          "<td>"+book.getElementsByTagName("price").item(0).getFirstChild().getNodeValue()+"</td>");
                  out.print(
          "<td>"+book.getElementsByTagName("publish").item(0).getFirstChild().getNodeValue()+"</td>");
                  Element bookdate
          =(Element)book.getElementsByTagName("date").item(0);
                  
          String day=bookdate.getElementsByTagName("day").item(0).getFirstChild().getNodeValue();
                  
          String month=bookdate.getElementsByTagName("month").item(0).getFirstChild().getNodeValue();
                  
          String year=bookdate.getElementsByTagName("year").item(0).getFirstChild().getNodeValue();
                  out.print(
          "<td>"+year+""+month+""+day+""+"</td>");
                  out.println();
              }
            
          %>
          </table>
          </body>
          </html>

          4)DOM修改XML文件
          修改XML文件就是在修改了DOM樹后重新寫入到XML文件中去,通常會遇到兩個方面的問題:
              Œ在XML文件中增加記錄:首先要在DOM樹中增加一個節點元素,然后在這個節點元素上增加子節點元素,并給相應的葉節點賦值,最后把DOM樹保存到XML文件中。
              ?在XML文件中修改節點的值,要修改XML文件中節點的值,需要先將XML文件讀入到DOM樹中,再遍歷DOM樹,并在遍歷的過程中找到相應的節點并修改其值,并把修改的DOM保存到XML文件中。
          5)DOM修改XML文件實例,所操作的XML文件依然是book.xml,用以創修改book.xml文件的文件是bookChange.jsp,代碼如下:

          <%@ page contentType="text/html;charset=gb2312"%>
          <%@ page import="javax.xml.parsers.*, javax.xml.transform.*,javax.xml.transform.dom.*"%>
          <%@ page import="javax.xml.transform.stream.*,java.io.*, org.w3c.dom.*"%>
          <html>
          <head>
          <title>DOM修改XML文件實例</title>
          </head>
          <body>
          <%
          DocumentBuilderFactory factory
          =DocumentBuilderFactory.newInstance();
          DocumentBuilder builder
          =factory.newDocumentBuilder();
          Document doc
          =builder.parse("C:/Program Files/Apache Software Foundation/Tomcat 6.0/webapps/readXml/book.xml");
          doc.normalize();
          //---取得變量---
          String name="精通Java EE項目案例";
          String author="劉乃麗";
          String price="85.00元";
          String publish="人民郵電出版社";  
          //---創建一個book對象---
          Text textseg;
          Element book
          =doc.createElement("book");
          //XML文件中添加一個book項目的具體元素
          Element bookname
          =doc.createElement("name");
          textseg
          =doc.createTextNode(name);
          bookname.appendChild(textseg);
          book.appendChild(bookname);
          Element bookauthor
          =doc.createElement("author");
          textseg
          =doc.createTextNode(author);
          bookauthor.appendChild(textseg);
          book.appendChild(bookauthor);
          Element bookprice
          =doc.createElement("price");
          textseg
          =doc.createTextNode(price);
          bookprice.appendChild(textseg);
          book.appendChild(bookprice);
          Element bookpublish
          =doc.createElement("publish");
          textseg
          =doc.createTextNode(publish);
          bookpublish.appendChild(textseg);
          book.appendChild(bookpublish);
          String day="01";
          String month="01";
          String year="2008";
          Element bookdate
          =doc.createElement("date");
          Element bookdateday
          =doc.createElement("day");
          textseg
          =doc.createTextNode(day);
          bookdateday.appendChild(textseg);
          Element bookdatemonth
          =doc.createElement("month");
          textseg
          =doc.createTextNode(month);
          bookdatemonth.appendChild(textseg);
          Element bookdateyear
          =doc.createElement("year");
          textseg
          =doc.createTextNode(year);
          bookdateyear.appendChild(textseg);
          bookdate.appendChild(bookdateday);
          bookdate.appendChild(bookdatemonth);
          bookdate.appendChild(bookdateyear);
          book.appendChild(bookdate);
          //創建好的節點添加到DOM樹中
          doc.getDocumentElement().appendChild(book);
          //用xslt把DOM樹輸出
          TransformerFactory tFactory
          =TransformerFactory.newInstance();
          Transformer transformer
          =tFactory.newTransformer();
          DOMSource source
          =new DOMSource(doc);
          StreamResult result
          =new StreamResult(new File("C:/Program Files/Apache Software Foundation/Tomcat 6.0/webapps/readXml/book.xml"));
          transformer.transform(source,result);
          %>
          <table border=1 align="center">
              
          <!--輸出表頭-->
              
          <tr bgcolor="yellow">
                  
          <td>書名</td>
                  
          <td>作者</td>
                  
          <td>定價</td>
                  
          <td>出版社</td>
                  
          <td>出版日期</td>        
              
          </tr>
          <% 
              
          //修改后讀取數據
              NodeList books
          =doc.getElementsByTagName("book");
              
          for(int i=0;i<books.getLength();i++){
                  book
          =(Element)books.item(i);
                  out.print(
          "<tr>");
                  out.print(
          "<td>"+book.getElementsByTagName("name").item(0).getFirstChild().getNodeValue()+"</td>");
                  out.print(
          "<td>"+book.getElementsByTagName("author").item(0).getFirstChild().getNodeValue()+"</td>");
                  out.print(
          "<td>"+book.getElementsByTagName("price").item(0).getFirstChild().getNodeValue()+"</td>");
                  out.print(
          "<td>"+book.getElementsByTagName("publish").item(0).getFirstChild().getNodeValue()+"</td>");
                  bookdate
          =(Element)book.getElementsByTagName("date").item(0);
                  
          day=bookdate.getElementsByTagName("day").item(0).getFirstChild().getNodeValue();
                  
          month=bookdate.getElementsByTagName("month").item(0).getFirstChild().getNodeValue();
                  
          year=bookdate.getElementsByTagName("year").item(0).getFirstChild().getNodeValue();
                  out.print(
          "<td>"+year+""+month+""+day+""+"</td>");
                  out.println();
              }
          %>    
          </table>
          </body>
          </html>
          5、SAX
          1). SAX ( Simple Application interface for XML ), 是一組程序設計接口,采用 observer 模式,將XML文件視為一個文字流的數據,在讀取XML 元素時觸發一系列的事件

          2). 使用DOM 時是將xml 文件解析為一個樹狀結構,并對樹中的節點進行操作
          使用SAX 加載XML文件時,他的操作像打開一個“順序的文件字符流”,在讀到XML元素的開始標記,結尾標記和內容標記時將產生一系列的事件
          如一個簡單的XML文件:<hello><message>hello XML!</message></hello>
          會相應的觸發:startDocument, startElement, characters, endElement, endDocument, 只需編寫這些事件處理程序就可以解析XML文件了

          3). SAX 可以高效的使用內存,因為SAX 只是順序的讀取XML 文件的內容,并不會將XML 文件完全加載,這樣就比DOM 的處理效率高
          但SAX 只能讀取XML 文件的內容,而不能更改XML 的內容,也不能隨機訪問XML 元素

          4). 在SAX 中有4個處理器是要實現的:ContentHandler,DTDHandler,EntityResolver,ErrorHandler,以處理不同的事件,這是比較麻煩的,
          幸好SAX 定義了一個 DefaultHandler 類把這幾個實現了,我們只需在 DefaultHandler中定義事件處理方法,然后注冊到XMLReader,而SAXParser封裝了XMLReader的實現類,
          SAXParser又是由SAXParserFactory提供的,所以我們實際用到的類只有:SAXParserFactory,SAXParser,DefaultHandler

          5). SAX 的解析步驟:
          (1)寫一個類繼承 DefaultHandler, 實現自己的事件處理方法
          (2)在主程序中建立 SAXParserFactory
          (3)可以設置這個factory 的參數
          (4)從這個factory 得到SAXParser
          (5)解析XML文件
          6)SAX解析XML實例,被解析的文件依然是book.xml,用以解析的文件是bookSaxDisplay.jsp,其代碼如下:
          <%@ page contentType="text/html;charset=GB2312" %>
          <%@ page import="javax.xml.parsers.*,
                          org.xml.sax.*,
                          org.xml.sax.helpers.
          *,
                          org.xml.sax.helpers.DefaultHandler,
                          java.io.
          *"
          %>

          <html>
            
          <head><title>用SAX解析并遍歷user.xml</title></head>
            
          <body>
          <%!
          static class SAXParseUser extends DefaultHandler{
              StringBuffer tempString
          =new StringBuffer();
              
          //文檔解析開始
              
          public void startDocument() throws SAXException {
                  tempString.append(
          "開始解析xml文件<br>");
              }
              
          //標簽解析開始
              
          public void startElement(String namespaceURI, String localName,String qName, Attributes atts) throws SAXException{
                  tempString.append(
          "開始解析結點,結點名稱:"+qName+"<br>");
                  
          //解析得到標簽所有的屬性
                  
          for(int i=0;i<atts.getLength();i++){
                      tempString.append(
          "&nbsp;&nbsp;屬性"+atts.getQName(i)+",值為:"+atts.getValue(i)+"<br>");        
                  }
              }
              
          //標簽解析結束
              
          public void endElement(String namespaceURI,String localName,String qName) throws SAXException{
                  tempString.append(
          "解析結點結束,結點名稱:"+qName+"<br>");
              }
              
          //字符串解析
              
          public void characters(char[] ch,int start,int length){
                  tempString.append(
          "&nbsp;&nbsp;解析出字符串,值為:'"+(new String(ch,start,length))+"'<br>");    
              }
              
          //文檔解析結束
              
          public void endDocument() throws SAXException {
                  tempString.append(
          "解析xml文件結束!<br>");
              }
              
          //得到解析結果
              
          public StringBuffer getPrintXML(){
                  return tempString;
              }
          }
          %>
          <%    //生成SAX解析器工廠長
              SAXParserFactory spf 
          = SAXParserFactory.newInstance();
              XMLReader xmlReader 
          = null;
              SAXParser saxParser
          =null;
              SAXParseUser saxParseUser
          =new SAXParseUser();
              
          String filename=pageContext.getServletContext().getRealPath("/book.xml");
              try {
                  
          // 創建一個解析器SAXParser對象
                  saxParser 
          = spf.newSAXParser();
                  
          // 得到SAXParser中封裝的SAX XMLReader
                  xmlReader 
          = saxParser.getXMLReader();
                  
          //設置解析時處理事件的對象
                  xmlReader.setContentHandler(saxParseUser);
                  
          //開始解析XML文件
                  xmlReader.parse(filename);
              }catch (Exception ex) {
                  System.out.println(ex);
              }
          %>      
                 
          <!--輸出解析結果-->
              
          <table border=1>
              
          <!--輸出表頭-->
              
          <tr >
                  
          <td align="center">內容</td>
                      
              
          </tr>
          <%
                  out.println(
          "<td>"+saxParseUser.getPrintXML()+"</td>");    
          %>  
           
          </table>
           
          </body>
          </html>
          主站蜘蛛池模板: 科技| 电白县| 曲靖市| 巴彦县| 湘乡市| 绍兴县| 买车| 上饶市| 东台市| 玉林市| 珲春市| 宁强县| 报价| 肃北| 平山县| 涞水县| 鄂州市| 衡南县| 天门市| 武汉市| 邹平县| 湘潭县| 芦山县| 罗平县| 灌南县| 鄂伦春自治旗| 陆川县| 赣州市| 台南县| 柳州市| 浙江省| 西安市| 宁化县| 五原县| 四川省| 融水| 江西省| 获嘉县| 宣威市| 大同县| 巴东县|