firtre

          小螞蟻,定語沒想好。 精靈古怪,不是我。

          XML初識篇

           XML 是一種數據格式。

          讀取XML文件內容,就需要解析器。
          最普通的 XML 處理工作是 解析 XML 文檔。解析包括讀取 XML 文檔并確定其結構和內容。
          XML 編程的一個好處是可以使用開放源代碼的、免費的 XML 解析器讀取 XML 文檔。
          為了簡化編寫處理 XML 的 Java 程序,已經建立了多種編程接口。
          主要的四個接口:
          • Document Object Model (DOM,文檔對象模型),Level 2
          • Simple API for XML (SAX), Version 2.0
          • JDOM, Jason Hunter 和 Brett McLaughlin 創立的一種簡單 Java API
          • Java API for XML Processing (JAXP)

          使用 DOM、SAX 或 JDOM 處理 XML 文檔的內容。

          如果使用 DOM 或 SAX,則使用 JAXP 創建解析器。

          如果使用 JDOM,則 JDOM 庫為您創建解析器。

          解析器的類型:

          • 驗證和非驗證解析器
          • 支持一種或多種 XML Schema 語言的解析器
          • 支持 Document Object Model (DOM) 的解析器
          • 支持 Simple API for XML (SAX) 的解析器

          XML文件的類型:

        1. 結構良好的文檔:這類文檔符合 XML 基本規則(屬性必須放在引號中、標簽必須正確嵌套等等)。
        2. 有效文檔:這些結構良好的文檔同時還符合文檔類型定義(DTD)或 XML Schema 所定義的規則。
        3. 無效文檔:所有其他文檔。
        4. (如果您有一個 XML 文檔符合 XML 的基本規則,那么它就是一個 結構良好的 文檔。如果該文檔還滿足您的公司所定義的支出帳目文檔規則,那么它也是 有效的。 )

          如果 XML 解析器發現 XML 文檔不是結構良好的,XML Specification 要求解析器報告一個致命錯誤。但驗證是一個不同的問題。驗證解析器 在解析時驗證 XML 文檔,而 非驗證解析器 不驗證文檔。換句話說,如果一個 XML 文檔是結構良好的,那么非驗證解析器并不關心文檔是否符合 DTD 或模式中定義的規則,甚至不關心該文檔是否有這樣的規則(原因:驗證需要大量工作)

          設置:

          1首先請訪問 Apache XML Project (http://xml.apache.org/xerces2-j/) 上的 Xerces XML 解析器主頁。您也可以直接去 下載頁面 (http://xml.apache.org/xerces2-j/download.cgi)。

          2解壓從 Apache 下載的文件。根據解析器版本的不同,這樣將會創建名為 xerces-2_5_0 或者類似名稱的目錄。所需要的 JAR 文件(xercesImpl.jarxml-apis.jar)應該出現在 Xerces 根目錄下。

          3訪問 JDOM 項目站點 并下載最新版本的 JDOM (http://jdom.org/)。

          4解壓從 JDOM 下載的文件,這樣將建立名為 jdom-b9 或者類似名稱的目錄。所需要的 JAR 文件(jdom.jar)應該在 build 目錄中。

          5最后請下載本教程的示例壓縮文件 ,并解壓該文件。

          6把當前目錄 (.)、xercesImpl.jarxml-apis.jarjdom.jar 添加到 CLASSPATH 變量中。

          使用解析器:

          1創建一個解析器對象

          2使解析器指向您的 XML 文檔

          3處理結果


          SAX:
          Simple API for XML (SAX) API 是處理 XML 文檔內容的一種替代方法。它的設計目標是更少的內存占用,但是把更多的工作交給了程序員。SAX 和 DOM 是互補的,有各自的適用環境。
           

          當使用 SAX 解析器解析一個 XML 文檔時,解析器在讀取文檔的過程中會生成一系列的事件。至于如何處理這些事件則取決于您。下面列出了一小部分您在 XML 文檔時可能遇到的事件:

          • startDocument 事件。
          • 對于每個元素,在元素開始時有 startElement 事件,元素結束時有 endElement 事件。
          • 如果元素包含內容,對于文本將出現 characters 事件,對于子元素將出現 startElementendElement 事件,依此類推。
          • endDocument 事件。

          和 DOM 一樣,SAX 解析器也忽略了某些細節,如屬性出現的順序。

          SAX 和 DOM 都過于復雜,

          和 DOM 類似,JDOM 也提供一個對象樹表示 XML 文檔,但是這些對象工作的方式對 Java 程序員更直觀。要記住,JDOM 在背后包含使用普通 SAX 或 DOM 解析器的適配器;JDOM 對所有主要的(和幾個次要的) Java XML 解析器都提供了適配器,因此不必擔心您的 Java XML 解析器是否支持 JDOM。JDOM 在幕后使用一個解析器不需要您的干涉。

          DOM

          DOM 是處理 XML 文檔結構的一種接口。作為一個 W3C 項目,DOM 的設計目標是提供一組對象和方法,使程序員的工作更輕松。

          當使用 DOM 解析器解析一個 XML 文檔時,您得到一個層次化的數據結構(DOM 樹),它表示解析器在 XML 文檔中發現的所有內容。然后您可以使用 DOM 函數操縱這棵樹。您可以搜索樹中的內容、移動分支、增加新的分支或者刪除樹的一部分。

          DOM 解析器返回一個樹狀結構,這個 DOM 樹包含一些 Node。從 Java 語言的角度看,Node 是一個接口。Node 是 DOM 的基本數據類型,DOM 樹中的所有事物都是這種或那種類型的 Node

          DOM Level 1 還定義了 Node 接口的幾種子接口:

          • Element:表示源文檔中的一個 XML 元素。
          • Attr:表示 XML 元素的一個屬性。
          • Text:一個元素的內容。這意味著帶有文本的元素包含文本節點孩子,元素的文本 不是 元素本身的一個屬性。
          • Document:表示整個 XML 文檔。解析的每個 XML 文檔中有且只有一個 Document 對象。給定一個 Document 對象就可以找到 DOM 樹的根,從這個根可以使用 DOM 函數讀和操縱樹。

          注意:“元素”和“標簽”這兩個詞有不同的含義。元素 是指起始元素、結束元素以及兩者之間的一切內容,包括屬性、文本、注釋以及子元素。標簽 是一對<尖括號>和兩者之間的內容,包括元素名和所有屬性。比如 <p class="blue"> 是一個標簽,</p> 也是;而 <p class="blue">The quick brown fox</p> 是一個元素。

          DOM 經常要用到以下方法:

          • Document.getDocumentElement():返回 DOM 樹的根。(該函數是 Document 接口的一個方法,沒有定義其他的 Node 子類型。)
          • Node.getFirstChild()Node.getLastChild():返回給定 Node 的第一個和最后一個孩子。
          • Node.getNextSibling()Node.getPreviousSibling():返回給定 Node 的下一個和上一個兄弟。
          • Element.getAttribute(String attrName):對于給定的 Element,返回名為 attrName 的屬性的值。如果需要 "id" 屬性的值,可以使用 Element.getAttribute("id")。如果該屬性不存在,該方法返回一個空字符串 ("")。

           

          第一個應用程序是 DomOne.java,這段簡單的 Java 代碼完成四件事:

          1. 掃描命令行得到 XML 文件名
          2. 創建一個解析器對象
          3. 告訴解析器解析命令行中給定的 XML 文件
          4. 遍歷 DOM 結果樹向標準輸出打印各種節點的內容

          第 1 步:掃描命令行


          掃描命令行相對而言非常簡單。只需要查看一個參數,并假定該參數是一個文件名或 URI。如果命令行中沒有參數,則打印一個錯誤消息并退出:

          public static void main(String argv[])
          {
          if (argv.length == 0 ||
          (argv.length == 1 && argv[0].equals("-help")))
          {
          System.out.println("\nUsage:  java DomOne uri");
          System.out.println("   where uri is the URI of the XML " +
          "document you want to print.");
          System.out.println("   Sample:  java DomOne sonnet.xml");
          System.out.println("\nParses an XML document, then writes " +
          "the DOM tree to the console.");
          System.exit(1);
          }
          DomOne d1 = new DomOne();
          d1.parseAndPrint(argv[0]);
          }
          

          第 2 步:創建一個解析器對象

          下面的代碼說明了先創建一個工廠對象,然后工廠對象創建解析器:

          public void parseAndPrint(String uri)
          {
          Document doc = null;
          try
          {
          DocumentBuilderFactory dbf =
          DocumentBuilderFactory.newInstance();
          DocumentBuilder db = dbf.newDocumentBuilder();
          . . .
          

            第 3 步:解析 XML 文件

          現在您已經創建了解析器,告訴它解析哪個文件(或 URI)很簡單:

          doc = db.parse(uri);
          

            第 4 步:打印 DOM 樹的內容
           

          最后一項任務是打印 DOM 樹的內容。因為 DOM 樹中的一切事物都是這種或那種類型的 Node,您需要用遞歸的方法遍歷并打印其中的內容。策略是調用該方法打印一個節點。該方法將打印那個節點,并對該節點的每個孩子調用自身。如果這些孩子還有孩子,該方法將對這些孩子調用自身。下面是一個例子:

            if (doc != null)
          printDomTree(doc);
          . . .
          }
          public void printDomTree(Node node)
          {
          int type = node.getNodeType();
          switch (type)
          {
          // print the document element
          case Node.DOCUMENT_NODE:
          {
          System.out.println("<?xml version=\"1.0\" ?>");
          printDomTree(((Document)node).getDocumentElement());
          break;
          }
          
          

          printDomTree 方法以一個 Node 作為參數。如果該 Node 是一個文檔節點,就打印一個 XML 聲明,然后對文檔元素(包含文檔其他內容的元素)調用 printDomTree。文檔元素基本上總是有其他孩子,因此 printDomTree 也將對這些孩子調用自身。這種遞歸算法可以遍歷整個 DOM 樹并把內容打印到命令行中。

          以下是 printDomTree 對元素節點的處理:

              case Node.ELEMENT_NODE:
          {
          System.out.print("<");
          System.out.print(node.getNodeName());
          NamedNodeMap attrs = node.getAttributes();
          for (int i = 0; i < attrs.getLength(); i++)
          printDomTree(attrs.item(i));
          System.out.print(">");
          if (node.hasChildNodes())
          {
          NodeList children = node.getChildNodes();
          for (int i = 0; i < children.getLength(); i++)
          printDomTree(children.item(i));
          }
          System.out.print("</");
          System.out.print(node.getNodeName());
          System.out.print('>');
          break;
          }
          
          

          對于元素節點,您需要打印一個左尖括號和結點名稱。如果該元素有屬性,就對每個屬性調用 printDomTree。(技術上講,這里可以使用 Attr.getName()Attr.getValue() 打印屬性,我這樣做是為了說明 DOM 樹中的一切都是 Node。)一旦打印完所有的屬性,就可以對該節點所包含的所有子元素再次調用 printDomTree。最后一步是在處理完所有的子元素之后打印結束元素。

          處理屬性節點和文本節點很簡單。對于屬性,需要輸出一個空格、屬性名、等號、開雙引號、屬性值和閉雙引號。(這里簡化了,屬性值可以使用單引號和雙引號,如果愿意您完全可以修正這個問題。)

          處理文本節點最簡單,只需要輸出文本就可以了。以下是這兩種節點類型的代碼:

              case Node.ATTRIBUTE_NODE:
          {
          System.out.print(" " + node.getNodeName() + "=\"" +
          ((Attr)node).getValue() + "\"");
          break;
          }
          case Node.TEXT_NODE:
          {
          System.out.print(node.getNodeValue());
          break;
          }
          
          

          盡管這里只是打印 DOM 樹的內容,但多數圍繞著 DOM 建立的 XML 應用程序都使用這種四個步驟的模式,第四步是遞歸處理例程。

          運行 DomOne

          在您解壓示例文件的目錄下鍵入:

          javac DomOne.java
          

          (記住 Java 語言是區分大小寫的。)如果沒有任何錯誤,鍵入:

          java DomOne sonnet.xml
          

          解析并顯示文件 sonnet.xml

          如果一切都和預期的一樣,您應該看到類似這樣的內容:

          C:\xml-prog-java>java DomOne sonnet.xml
          <?xml version="1.0" ?>
          <sonnet type="Shakespearean">
          <author>
          <lastName>Shakespeare</lastName>
          <firstName>William</firstName>
          <nationality>British</nationality>
          <yearOfBirth>1564</yearOfBirth>
          <yearOfDeath>1616</yearOfDeath>
          </author>
          <title>Sonnet 130</title>
          <lines>
          <line>My mistress' eyes are nothing like the sun,</line>
          <line>Coral is far more red than her lips red.</line>
          <line>If snow be white, why then her breasts are dun,</line>
          <line>If hairs be wires, black wires grow on her head.</line>
          . . .
          </lines>
          

          待續
          摘自IBM在線學習

          posted on 2008-02-18 16:45 笨蛋 閱讀(243) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 平塘县| 平舆县| 连云港市| 东宁县| 河间市| 富阳市| 谢通门县| 宜城市| 陇川县| 巴里| 沈丘县| 神池县| 广丰县| 安远县| 武陟县| 孟州市| 四川省| 嘉禾县| 延川县| 嘉祥县| 海丰县| 肥城市| 英吉沙县| 泽普县| 炎陵县| 天台县| 沧源| 灵川县| 高雄县| 康定县| 农安县| 洱源县| 牙克石市| 论坛| 南陵县| 沂源县| 仁化县| 佛冈县| 福贡县| 乌苏市| 承德县|