posts - 8,  comments - 4,  trackbacks - 0

          編寫使用這些接口的 Java 代碼

          通過(guò)在您的應(yīng)用程序中使用 XMLBean 接口,可以編寫使用新類型的代碼,以便基于該 Schema 對(duì) XML 進(jìn)行處理。下面的示例將提取有關(guān)訂購(gòu)單 XML 中的每個(gè)訂購(gòu)商品的信息,并計(jì)算商品的數(shù)量,然后計(jì)算其價(jià)格總和。請(qǐng)?zhí)貏e注意基于 Schema 生成的類型以及作為 org.openuri.easypo 包的一部分而導(dǎo)入的類型的使用情況。

          printItems 方法接收包含訂購(gòu)單 XML 文件的 File 對(duì)象。

          package docs.xmlbeans;
          
          import java.io.File;
          import com.bea.xml.*;
          import org.openuri.easypo.PurchaseOrderDocument;
          import org.openuri.easypo.PurchaseOrder;
          import org.openuri.easypo.LineItem;
          
          public class POHandler 
          {
              public static void printItems(File po) throws Exception 
              {
                  /*
                   * 所有 XMLBean Schema 類型都提供嵌套的 Factory 類,您可以使用它
                   * 將 XML 綁定到該類型,或者創(chuàng)建該類型的新實(shí)例。
                   * 請(qǐng)注意,像該類型一樣的“Document”類型是 XMLBean
                   * 構(gòu)造,用于表示全局元素。它為您提供了一種
                   * 獲取和設(shè)置整個(gè)元素的內(nèi)容的方法。
                   *
                   * 此外,只有在所解析的 XML 遵守
                   * Schema 的情況下,parse 方法才會(huì)成功。
                   */
                  PurchaseOrderDocument poDoc =
                      PurchaseOrderDocument.Factory.parse(po);
          
                  /*
                   * PurchaseOrder 類型表示 purchase-order 元素的
                   * 復(fù)雜類型。
                   */
                  PurchaseOrder po = poDoc.getPurchaseOrder();
          
                  /*
                   * 當(dāng)某個(gè)元素可能作為子元素出現(xiàn)多次時(shí),
                   * Schema 編譯器將生成引用該元素
                   * 的多個(gè)實(shí)例的方法。line-item 元素
                   * 的 maxOccurs 特性值指定為“unbounded”,這意味著
                   * 它可以根據(jù)需要在一個(gè)實(shí)例中出現(xiàn)多次。
                   * 因此存在 getLineItemArray 和 setLineItemArray 等方法。 
                   */
                  LineItem[] lineitems = po.getLineItemArray();
                  System.out.println("Purchase order has " + lineitems.length + " line items.");
          
          double totalAmount = 0.0;
                  int numberOfItems = 0;
          
                  /*
                   * 循環(huán)遍歷 line-item 元素,方法是使用所生成的存取程序
                   * 獲取子元素的值,如 description、quantity 以及
                   * price。
                   */
                  for (int j = 0; j < lineitems.length; j++) 
                  {
                      System.out.println(" Line item:" + j);
                      System.out.println(
                          "   Description:" + lineitems[j].getDescription());
                      System.out.println("   Quantity:" + lineitems[j].getQuantity());
                      System.out.println("   Price:" + lineitems[j].getPrice());
                      numberOfItems += lineitems[j].getQuantity();
                      totalAmount += lineitems[j].getPrice() * lineitems[j].getQuantity();
                  }
                  System.out.println("Total items:" + numberOfItems);
                  System.out.println("Total amount:" + totalAmount);
              }
          }
          

          請(qǐng)注意,基于 Schema 所生成的類型反映了 XML 中的內(nèi)容:

          • PurchaseOrderDocument,表示全局根元素。
          • getPurchaseOrder 方法,返回包含子元素(其中包括 line-item)的 PurchaseOrderDocument.PurchaseOrder 類型。getLineItemArray 方法,返回包含 line-item 元素的 LineItem 數(shù)組。
          • 其他方法(如 getQuantitygetPrice 等等)是根據(jù) Schema 的描述自然得出的,其作用是返回 line-item 元素的相應(yīng)子元素。
          • 包含這些類型的包的名稱是從 Schema 的目標(biāo)名稱空間派生得到的。

          所生成的類型名稱的大小寫和標(biāo)點(diǎn)符號(hào)遵從 Java 約定。此外,當(dāng)該示例解析文件中的 XML 時(shí),其他 parse 方法支持 Java InputStream 對(duì)象、Reader 對(duì)象等等。

          前面的 Java 代碼將在控制臺(tái)中打印下列內(nèi)容:

          Purchase order has 3 line items.
           Line item 0
             Description:Burnham's Celestial Handbook, Vol 1
             Quantity: 2
             Price: 21.79
           Line item 1
             Description:Burnham's Celestial Handbook, Vol 2
             Quantity: 2
             Price: 19.89
          Total items: 4
          Total amount: 41.68

          基于 Schema 創(chuàng)建新的 XML 實(shí)例

          您已經(jīng)看到 XMLBean 提供一個(gè) "factory" 類,您可以使用該類來(lái)創(chuàng)建新的實(shí)例。下面的示例創(chuàng)建新的 purchase-order 元素,并添加 customer 子元素。然后它會(huì)插入 nameaddress 子元素,從而創(chuàng)建元素,并通過(guò)僅調(diào)用一次它們的 set 方法來(lái)設(shè)置它們的值。

          public PurchaseOrderDocument createPO()
          {
              PurchaseOrderDocument newPODoc = PurchaseOrderDocument.Factory.newInstance();
              PurchaseOrder newPO = newPODoc.addNewPurchaseOrder();
              Customer newCustomer = newPO.addNewCustomer();
              newCustomer.setName("Doris Kravitz");
              newCustomer.setAddress("Bellflower, CA");
              return newPODoc;
          }
          

          下面是生成的 XML。請(qǐng)注意,XMLBean 通過(guò)使用 "ns1"(或 "namespace 1")前綴,并基于 Schema 來(lái)分配正確的名稱空間。在實(shí)際工作中,前綴本身并不是真的很重要,它只是用來(lái)定義名稱空間的名稱空間 URI (http://openuri.org/easypo)。前綴僅僅是表示它的一個(gè)標(biāo)記。

          <ns1:purchase-order xmlns:ns1="http://openuri.org/easypo">
              <ns1:customer>
                  <ns1:name>Doris Kravitz</ns1:name>
                  <ns1:address>Bellflower, CA</ns1:address>
              </ns1:customer>
          </ns1:purchase-order>
          

          請(qǐng)注意,所有類型(包括基于 Schema 生成的類型)都是對(duì) XmlObject 的繼承,因此都提供了 Factory 類。有關(guān)適合使用 XmlObject 的類型系統(tǒng)的概述,請(qǐng)參閱 XMLBean 對(duì)內(nèi)置 Schema 類型的支持。有關(guān)參考信息,請(qǐng)參閱 XmlObject Interface

          XMLBean 層次

          上面的示例中使用的生成類型實(shí)際上是 XMLBean 類型的層次的一部分。這種層次是 XMLBean 用來(lái)直觀展現(xiàn) Schema 視圖的一種方法。層次的頂部是 XmlObject,即 XMLBean 類型的基礎(chǔ)接口。在該級(jí)別的下面,有兩個(gè)主要的類型類別:生成類型(表示用戶派生的 Schema 類型)和包括類型(表示內(nèi)置 Schema 類型)。

          本主題已介紹了生成類型。有關(guān)詳細(xì)信息,請(qǐng)參閱從用戶派生的 Schema 類型生成的 Java 類型

          內(nèi)置類型支持

          除了基于指定的 Schema 所生成的類型以外,XMLBean 還提供了 46 種特別的 Java 類型,這些類型是對(duì) XML Schema 規(guī)范所定義的 46 種內(nèi)置類型的鏡像。例如,Schema 定義了 xs:stringxs:decimalxs:int,而 XMLBean 提供了 XmlStringXmlDecimalXmlInt。其中的每個(gè)類型也是繼承自 XmlObject,該類型與內(nèi)置 Schema 類型 xs:anyType 對(duì)應(yīng)。

          通過(guò) XMLBean,您就可以將 XML 數(shù)據(jù)作為這些內(nèi)置類型進(jìn)行處理。如果您的 Schema 包括一個(gè)類型為 xs:int 的元素,XMLBean 將提供一個(gè)可以返回 XmlInt 的生成方法。此外,就像您在前面的示例中所看到的,對(duì)于大多數(shù)類型來(lái)說(shuō),還將有一個(gè)返回純 Java 類型(如 int)的方法。下面的兩行代碼返回 quantity 元素的值,但將其作為其他類型返回。

          // 返回以“x”開頭的簡(jiǎn)單類型的方法。
          XmlInt xmlQuantity = lineitems[j].xgetQuantity();
          // 返回純 Java 類型的方法。
          int javaQuantity = lineitems[j].getQuantity();
          

          在某種意義上,這兩種 get 方法均導(dǎo)航至 quantity 元素;getQuantity 方法更深入一步,在返回元素值之前,將其轉(zhuǎn)換為最適合的純 Java 類型。(XMLBean 還為您提供了一種在使用 XML 的同時(shí)對(duì)它進(jìn)行驗(yàn)證的方法。)

          如果您對(duì) XML Schema 有所了解,那么您會(huì)覺得 XMLBean 類型看起來(lái)非常直觀。如果您對(duì) XML Schema 知之甚少,可以使用您自己的 Schema 以及基于它們的 XML 實(shí)例來(lái)對(duì) XMLBean 進(jìn)行試驗(yàn),以了解詳細(xì)的信息。

          有關(guān)基于 Schema 生成的類型的方法的詳細(xì)信息,請(qǐng)參閱 從 Schema 生成的類型的方法。有關(guān) XMLBean 如何表示內(nèi)置 Schema 類型的詳細(xì)信息,請(qǐng)參閱 XMLBean 對(duì)內(nèi)置 Schema 類型的支持

          使用 XQuery 表達(dá)式

          使用 XMLBean,可以通過(guò) XQuery 查詢 XML 中特定的數(shù)據(jù)塊。XQuery 有時(shí)也稱為“用于 XML 的 SQL”,因?yàn)樗峁┝艘环N直接從 XML 文檔訪問(wèn)數(shù)據(jù)的機(jī)制,這與 SQL 所提供的、訪問(wèn)傳統(tǒng)數(shù)據(jù)庫(kù)數(shù)據(jù)的機(jī)制十分類似。

          XQuery 的一些語(yǔ)法是從 XPath 借鑒來(lái)的,后者是一種用于在 XML 中指定嵌套數(shù)據(jù)的語(yǔ)法。下面的示例返回 price 子元素的值小于或等于 20.00 的所有 line-item 元素:

          PurchaseOrderDocument doc = PurchaseOrderDocument.Factory.parse(po);
          
          /*
           * XQuery 表達(dá)式是由下面兩個(gè)字符串組成的。為方便起見,
           * 在這里分別對(duì)它們進(jìn)行聲明。第一個(gè)字符串聲明
           * 在查詢表達(dá)式中使用的名稱空間前綴;第二個(gè)字符串
           * 聲明表達(dá)式本身。
           */
          String nsText = "declare namespace po = 'http://openuri.org/easypo'";
          String pathText = "$this/po:purchase-order/po:line-item[po:price <= 20.00]";
          String queryText = nsText + pathText;
          
          XmlCursor itemCursor = doc.newCursor().execQuery(queryText);
          System.out.println(itemCursor.xmlText());
          

          上述代碼在文檔的開頭創(chuàng)建一個(gè)新的光標(biāo)。從那里,它使用 XmlCursor 接口的 execQuery 方法執(zhí)行查詢表達(dá)式。在本例中,該方法的參數(shù)是 XQuery 表達(dá)式,該表達(dá)式僅僅指出“從我當(dāng)前的位置,在 purchase-order 元素中導(dǎo)航,并檢索值小于或等于 20.00 的那些 line-item 元素”。$this 變量意味著“當(dāng)前的位置”。

          有關(guān) XQuery 的詳細(xì)信息,請(qǐng)參閱 W3C 網(wǎng)站中的 XQuery 1.0:An XML Query Language

          使用 XML 光標(biāo)

          在前面的示例中,您可能已經(jīng)注意到 XmlCursor 接口。除了提供一種執(zhí)行 XQuery 表達(dá)式的方法外,XML 光標(biāo)還提供一種用于操作數(shù)據(jù)的細(xì)粒度模型。XML 光標(biāo) API 與 DOM 的對(duì)象 API 類似,它只是一種指向特定數(shù)據(jù)塊的方式。因此,就像光標(biāo)有助于在字處理文檔中導(dǎo)航一樣,XML 光標(biāo)則定義了 XML 中的一個(gè)位置,您可以在該位置對(duì)選定的 XML 執(zhí)行操作。

          當(dāng)沒有可用的 Schema 時(shí),光標(biāo)是一種在 XML 文檔中移動(dòng)的理想方法。一旦光標(biāo)到達(dá)了您需要的位置,您就可以使用它執(zhí)行各種操作。例如,可以設(shè)置和獲取值、插入和刪除 XML 的片段、將 XML 的片段復(fù)制到文檔的其他部分,以及對(duì) XML 文檔進(jìn)行其他細(xì)粒度更改。

          下面的示例使用 XML 光標(biāo)導(dǎo)航到 customer 元素的 name 子元素。

          PurchaseOrderDocument doc = 
              PurchaseOrderDocument.Factory.parse(po);
          
          XmlCursor cursor = doc.newCursor();
          cursor.toFirstContentToken();
          cursor.toFirstChildElement();
          cursor.toFirstChildElement();
          System.out.println(cursor.getText());
          
          cursor.dispose();
          

          上述代碼執(zhí)行了哪些操作呢?與前面的示例一樣,代碼加載 File 對(duì)象中的 XML。加載文檔之后,代碼在它的起始位置處創(chuàng)建一個(gè)光標(biāo)。移動(dòng)光標(biāo)幾次,使它到達(dá)嵌套的 name 元素。一旦光標(biāo)到達(dá)該元素,getText 方法便會(huì)檢索該元素的值。

          posted on 2006-02-16 11:12 Parmy 閱讀(1085) 評(píng)論(0)  編輯  收藏

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          歡迎!

          <2006年2月>
          2930311234
          567891011
          12131415161718
          19202122232425
          2627281234
          567891011

          常用鏈接

          留言簿(1)

          隨筆檔案(8)

          搜索

          •  

          積分與排名

          • 積分 - 6228
          • 排名 - 2863

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 西贡区| 景洪市| 凯里市| 内乡县| 美姑县| 金乡县| 玉山县| 娄烦县| 湘乡市| 大竹县| 丰都县| 宜兰市| 罗城| 盐池县| 通州市| 凤阳县| 清河县| 敖汉旗| 康平县| 香河县| 建水县| 遂平县| 涡阳县| 南丰县| 镇江市| 黄龙县| 靖安县| 澎湖县| 盐源县| 朔州市| 常宁市| 东乡族自治县| 新源县| 双柏县| 宁晋县| 五河县| 湖口县| 通城县| 富平县| 合阳县| 化隆|