Cyh的博客

          Email:kissyan4916@163.com
          posts - 26, comments - 19, trackbacks - 0, articles - 220

          用DOM處理XML文檔

          Posted on 2009-12-20 14:07 啥都寫點(diǎn) 閱讀(350) 評論(0)  編輯  收藏 所屬分類: J2SE
             DOM(Document Object Model)是一種處理XML文檔的技術(shù),通過DOM能夠讀取、修改XML文檔。本例將介紹用DOM處理XML文檔,把一個描述學(xué)生信息的XML文檔讀到內(nèi)存中,構(gòu)成多個學(xué)生對象,然后把這些學(xué)生對象的信息保存到另一個XML文檔中。

               DOM將整個XML文檔讀到內(nèi)存中,用基本對象描述XML文檔的元素,基本對象之間以樹形的結(jié)構(gòu)組織。
               DOM常用的基本對象類有5個:

                      org.w3c.dom.Document:該類的對象代表了整個XML的文檔,所有其他的XML元素,都以一定的順序包含在Document對象內(nèi),排列成一個樹形結(jié)構(gòu),可以通過遍歷這棵樹來得到XML文檔的所有內(nèi)容,這也是對XML文檔操作的起點(diǎn)。
                      org.w3c.dom.Node:該類是一個接口類,定義了DOM結(jié)構(gòu)中的一個抽象的節(jié)點(diǎn)。
                      org.w3c.dom.NodeList:該對象代表了一個包含多個Node的列表。
                      org.w3c.dom.Element:該對象代表的是XML文檔中的標(biāo)簽元素,繼承與Node.在標(biāo)簽中可以包含屬性,因此Element對象中的存取其屬性的方法。
                      org.w3c.dom.Attr:該對象代表了某個標(biāo)簽中的屬性。繼承于Node,但是因為Attr實(shí)際上是包含在Element中的,所以Attr并不是DOM樹的一部分。
               通過DOM解析器工廠DocumentBuilderFactory的newDocumentBuilder方法可以創(chuàng)建一個DOM解析器對象,類型為DocumentBuilder,它的parse方法能夠?qū)ML文檔讀取到內(nèi)存,返回一個Document對象。
               通過DocumentBuilder的newDocument方法創(chuàng)建一個新的XML文檔,返回一個Document對象。通過Document的appendChild方法往文檔中添加子節(jié)點(diǎn)。
               使用JAXP(Java API for XML Processing)技術(shù)能將Document對象存儲到文件中。根據(jù)Document對象創(chuàng)建DOMSource,使用Transformer的transform方法將DOMSource轉(zhuǎn)換成XML文檔。


          /**-------------------------------------StudentBean.java-----------------------------------------------*/
          /**
           * 描述學(xué)生的JavaBean
           
          */

          public class StudentBean {
              
          // 學(xué)生姓名
              private String name;
              
          // 學(xué)生性別 
              private String gender;
              
          // 學(xué)生年齡
              private int age;
              
          // 學(xué)生電話號碼
              private String phone;

              
          public String toString(){
                  StringBuffer sb 
          = new StringBuffer();
                  sb.append(
          "姓名:").append(this.name).append(";  ");
                  sb.append(
          "性別:").append(gender).append(";  ");
                  sb.append(
          "年齡:").append(age).append(";  ");
                  sb.append(
          "電話:").append(phone);
                  
          return sb.toString();
              }

              
              
          /**
               * 
          @return 返回 age。
               
          */

              
          public int getAge() {
                  
          return age;
              }

              
          /**
               * 
          @param age 要設(shè)置的 age。
               
          */

              
          public void setAge(int age) {
                  
          this.age = age;
              }

              
          /**
               * 
          @return 返回 gender。
               
          */

              
          public String getGender() {
                  
          return gender;
              }

              
          /**
               * 
          @param gender 要設(shè)置的 gender。
               
          */

              
          public void setGender(String gender) {
                  
          this.gender = gender;
              }

              
          /**
               * 
          @return 返回 name。
               
          */

              
          public String getName() {
                  
          return name;
              }

              
          /**
               * 
          @param name 要設(shè)置的 name。
               
          */

              
          public void setName(String name) {
                  
          this.name = name;
              }

              
          /**
               * 
          @return 返回 phone。
               
          */

              
          public String getPhone() {
                  
          return phone;
              }

              
          /**
               * 
          @param phone 要設(shè)置的 phone。
               
          */

              
          public void setPhone(String phone) {
                  
          this.phone = phone;
              }

          }

          /**----------------------------------DomXML.java------------------------------------*/
          import java.io.File;
          import java.io.IOException;
          import java.util.ArrayList;
          import java.util.List;
          import java.util.Properties;

          import javax.xml.parsers.DocumentBuilder;
          import javax.xml.parsers.DocumentBuilderFactory;
          import javax.xml.parsers.ParserConfigurationException;
          import javax.xml.transform.OutputKeys;
          import javax.xml.transform.Transformer;
          import javax.xml.transform.TransformerException;
          import javax.xml.transform.TransformerFactory;
          import javax.xml.transform.dom.DOMSource;
          import javax.xml.transform.stream.StreamResult;

          import org.w3c.dom.DOMException;
          import org.w3c.dom.Document;
          import org.w3c.dom.Element;
          import org.w3c.dom.NodeList;
          import org.w3c.dom.Text;

          /**
           * dom的基本對象有5個:document,node,nodelist,element和attr
           * document對象代表了整個xml的文檔,所有其它的node,都以一定的順序包含在document對象之內(nèi),排列成一個樹形的結(jié)構(gòu),程序員可以通過遍歷這顆樹來得到xml文檔的所有的內(nèi)容,這也是對xml文檔操作的起點(diǎn)。我們總是先通過解析xml源文件而得到一個document對象,然后再來執(zhí)行后續(xù)的操作.
           * node對象是dom結(jié)構(gòu)中最為基本的對象,代表了文檔樹中的一個抽象的節(jié)點(diǎn)。在實(shí)際使用的時候,很少會真正的用到node這個對象,而是用到諸如element、attr、text等node對象的子對象來操作文檔。node對象為這些對象提供了一個抽象的、公共的根。雖然在node對象中定義了對其子節(jié)點(diǎn)進(jìn)行存取的方法,但是有一些node子對象,比如text對象,它并不存在子節(jié)點(diǎn),這一點(diǎn)是要注意的。
           * nodelist對象,顧名思義,就是代表了一個包含了一個或者多個node的列表.
           * element對象代表的是xml文檔中的標(biāo)簽元素,繼承于node,亦是node的最主要的子對象。在標(biāo)簽中可以包含有屬性,因而element對象中有存取其屬性的方法,而任何node中定義的方法,也可以用在element對象上面。
           * attr對象代表了某個標(biāo)簽中的屬性。attr繼承于node,但是因為attr實(shí)際上是包含在element中的,它并不能被看作是element的子對象,因而在dom中attr并不是dom樹的一部分,所以node中的getparentnode(),getprevioussibling()和getnextsibling()返回的都將是null。也就是說,attr其實(shí)是被看作包含它的element對象的一部分,它并不作為dom樹中單獨(dú)的一個節(jié)點(diǎn)出現(xiàn)。這一點(diǎn)在使用的時候要同其它的node子對象相區(qū)別。
           
          */

          public class DomXML {

              
          public static List readXMLFile(String inFile) throws Exception {
                  
          //    得到DOM解析器的工廠實(shí)例
                  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                  DocumentBuilder db 
          = null;
                  
          try {
                      
          // 從DOM工廠獲得DOM解析器
                      db = dbf.newDocumentBuilder();
                  }
           catch (ParserConfigurationException pce) {
                      System.err.println(pce); 
                      
          return null;
                  }


                  Document doc 
          = null;
                  
          try {
                      
          // 解析XML文檔的輸入流,得到一個Document
                      doc = db.parse(inFile);
                      
          // 對document對象調(diào)用normalize(),可以去掉xml文檔中作為格式化內(nèi)容的空白,
                      
          // 避免了這些空白映射在dom樹中成為不必要的text node對象。
                      
          // 否則你得到的dom樹可能并不是你所想象的那樣。
                      
          // 特別是在輸出的時候,這個normalize()更為有用。 
                      doc.normalize();
                  }
           catch (DOMException dom) {
                      System.err.println(dom.getMessage());
                      
          return null;
                  }
           catch (IOException ioe) {
                      System.err.println(ioe);
                      
          return null;
                  }


                  List studentBeans 
          = new ArrayList();
                  StudentBean studentBean 
          = null;
                  
          //    得到XML文檔的根節(jié)點(diǎn)“學(xué)生花名冊”
                  Element root = doc.getDocumentElement();
                  
          //    取"學(xué)生"元素列表
                  NodeList students = root.getElementsByTagName("學(xué)生");
                  
          for (int i = 0; i < students.getLength(); i++{
                      
          //    依次取每個"學(xué)生"元素
                      Element student = (Element) students.item(i);
                      
          //    創(chuàng)建一個學(xué)生的Bean實(shí)例
                      studentBean = new StudentBean();
                      
          //    取學(xué)生的性別屬性
                      studentBean.setGender(student.getAttribute("性別"));
                      
                      
          //    取“姓名”元素
                      NodeList names = student.getElementsByTagName("姓名");
                      
          if (names.getLength() == 1{
                          Element e 
          = (Element) names.item(0);
                          
          // 取姓名元素的第一個子節(jié)點(diǎn),即為姓名的值節(jié)點(diǎn)
                          Text t = (Text) e.getFirstChild();
                          
          // 獲取值節(jié)點(diǎn)的值
                          studentBean.setName(t.getNodeValue());
                      }


                      
          // 取“年齡”元素
                      NodeList ages = student.getElementsByTagName("年齡");
                      
          if (ages.getLength() == 1{
                          Element e 
          = (Element) ages.item(0);
                          Text t 
          = (Text) e.getFirstChild();
                          studentBean.setAge(Integer.parseInt(t.getNodeValue()));
                      }


                      
          //    取“電話”元素
                      NodeList phones = student.getElementsByTagName("電話");
                      
          if (phones.getLength() == 1{
                          Element e 
          = (Element) phones.item(0);
                          Text t 
          = (Text) e.getFirstChild();
                          studentBean.setPhone(t.getNodeValue());
                      }

                      
          // 將新建的Bean加到結(jié)果列表中
                      studentBeans.add(studentBean);
                  }

                  
          // 返回結(jié)果列表
                  return studentBeans;
              }

              
              
          /**
               * 用DOM寫XML文檔,把學(xué)生信息以XML文檔的形式存儲
               * 
          @param outFile    輸出XML文檔的路徑
               * 
          @param studentGeans    學(xué)生信息
               * 
          @throws Exception
               
          */

              
          public static String writeXMLFile(String outFile, List studentGeans) throws Exception {
                  
          //為解析XML作準(zhǔn)備,創(chuàng)建DocumentBuilderFactory實(shí)例,指定DocumentBuilder 
                  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                  DocumentBuilder db 
          = null;
                  
          try {
                      db 
          = dbf.newDocumentBuilder();
                  }
           catch (ParserConfigurationException pce) {
                      System.err.println(pce);
                      
          return null;
                  }

                  
          // 新建一個空文檔
                  Document doc = null;
                  doc 
          = db.newDocument();

                  
          // 下面是建立XML文檔內(nèi)容的過程.
                  
          // 先建立根元素"學(xué)生花名冊",并添加到文檔中 
                  Element root = doc.createElement("學(xué)生花名冊");
                  doc.appendChild(root);

                  
          //取學(xué)生信息的Bean列表 
                  for (int i = 0; i < studentGeans.size(); i++{
                      
          //    依次取每個學(xué)生的信息 
                      StudentBean studentBean = (StudentBean) studentGeans.get(i);
                      
                      
          //    建立“學(xué)生”元素,有一個“性別”屬性,然后添加到根元素 
                      Element student = doc.createElement("學(xué)生");
                      student.setAttribute(
          "性別", studentBean.getGender());
                      root.appendChild(student);
                      
                      
          //    建立"姓名"元素,添加到學(xué)生下面 
                      Element name = doc.createElement("姓名");
                      student.appendChild(name);
                      
          // 為“姓名”元素賦值
                      Text tName = doc.createTextNode(studentBean.getName());
                      name.appendChild(tName);
                      
                      
          // 建立“年齡”元素,然后給元素賦值
                      Element age = doc.createElement("年齡");
                      student.appendChild(age);
                      Text tAge 
          = doc    .createTextNode(
                              String.valueOf(studentBean.getAge()));
                      age.appendChild(tAge);
                      
                      
          // 建立“電話”元素,然后給元素賦值
                      Element phone = doc.createElement("電話");
                      student.appendChild(phone);
                      Text tPhone 
          = doc.createTextNode(studentBean.getPhone());
                      phone.appendChild(tPhone);
                  }

                  
                  
          //    把XML文檔輸出到指定的文件 
                  return domDocToFile(doc, outFile, "GB2312");
              }

              
              
          /**
               * 使用JAXP將DOM對象寫到XML文檔里
               * 
          @param doc    DOM的文檔對象
               * 
          @param fileName    寫入的XML文檔路徑
               * 
          @param encoding    XML文檔的編碼
               * 
          @throws TransformerException
               
          */

              
          public static String domDocToFile(Document doc, String fileName, String encoding)
                      
          throws TransformerException {
                  
          // 首先創(chuàng)建一個TransformerFactory對象,再由此創(chuàng)建Transformer對象。
                  
          // Transformer類相當(dāng)于一個XSLT引擎。通常我們使用它來處理XSL文件,
                  
          // 但是在這里我們使用它來輸出XML文檔。
                  TransformerFactory tFactory = TransformerFactory.newInstance();
                  Transformer transformer 
          = tFactory.newTransformer();
                  
                  
          // 獲取Transformser對象的輸出屬性,亦即XSLT引擎的缺省輸出屬性,是java.util.Properties對象
                  Properties properties = transformer.getOutputProperties();
                  
          // 設(shè)置新的輸出屬性:輸出字符編碼為GB2312,這樣可以支持中文字符,
                  
          // XSLT引擎所輸出的XML文檔如果包含了中文字符,可以正常顯示。
                  properties.setProperty(OutputKeys.ENCODING, "GB2312");
                  
          // 這里設(shè)置輸出為XML格式,實(shí)際上這是XSLT引擎的默認(rèn)輸出格式
                  properties.setProperty(OutputKeys.METHOD, "xml");
                  transformer.setOutputProperties(properties);
                  
                  
          // 創(chuàng)建一個DOMSource對象,該構(gòu)造函數(shù)的參數(shù)可以是一個Document對象
                  DOMSource source = new DOMSource(doc);
                  
          // 創(chuàng)建XSLT引擎的輸出對象,這里將輸出寫如文件
                  File file = new File(fileName);
                  StreamResult result 
          = new StreamResult(file);
                  
                  
          // 執(zhí)行DOM文檔到XML文件的轉(zhuǎn)換
                  transformer.transform(source, result);
                  
                  
          // 將輸出文件的路徑返回
                  return file.getAbsolutePath();
              }


              
          public static void main(String[] args) {
                  String inFileName 
          = "students.xml";
                  String outFileName 
          = "students_new.xml";
                  
          try {
                      List studentBeans 
          = DomXML.readXMLFile(inFileName);
                      DomXML.writeXMLFile(outFileName, studentBeans);
                  }
           catch (Exception e) {
                      e.printStackTrace();
                  }

              }

          }

          /**----------------------------------文件名:studnet.xml------------------------------------*/
          <?xml version="1.0" encoding="GB2312"?>
          <學(xué)生花名冊>
           <學(xué)生 性別 = "男">
            <姓名>張三</姓名>
            <年齡>145</年齡>
            <電話>62875555</電話>
           </學(xué)生>
           <學(xué)生 性別 = "女">
            <姓名>李四</姓名>
            <年齡>16</年齡>
            <電話>82734254</電話>
           </學(xué)生>
          </學(xué)生花名冊>





















          用DOM生成的student_new.xml文件的內(nèi)容如下:

          /**----------------------------------文件名:studnet_new.xml------------------------------------*/
          <?xml version="1.0" encoding="GB2312"?>
          <學(xué)生花名冊>
           <學(xué)生 性別 = "男">
            <姓名>張三</姓名>
            <年齡>145</年齡>
            <電話>62875555</電話>
           </學(xué)生>
           <學(xué)生 性別 = "女">
            <姓名>李四</姓名>
            <年齡>16</年齡>
            <電話>82734254</電話>
           </學(xué)生>
          </學(xué)生花名冊>

























                                                                                                                 --    學(xué)海無涯
                  

          主站蜘蛛池模板: 崇明县| 七台河市| 丹棱县| 建始县| 凤台县| 上林县| 双辽市| 旬阳县| 益阳市| 密山市| 德格县| 南涧| 莲花县| 拜城县| 武强县| 巫山县| 桃园市| 长海县| 金山区| 泗阳县| 合山市| 华坪县| 涿鹿县| 县级市| 巴林左旗| 新宁县| 甘孜县| 沂南县| 龙泉市| 遂平县| 海伦市| 张家川| 临高县| 长兴县| 抚宁县| 定南县| 成安县| 灵璧县| 那坡县| 凤山市| 商河县|