<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    jinfeng_wang

    G-G-S,D-D-U!

    BlogJava 首頁 新隨筆 聯(lián)系 聚合 管理
      400 Posts :: 0 Stories :: 296 Comments :: 0 Trackbacks
    http://dev2dev.bea.com.cn/techdoc/20060713845.html


    XMLBEANS 2.0 —— 一位JAVA開發(fā)人員的視點

    時間:2006-07-13
    作者:Jacob DannerRaj Alagumalai
    瀏覽次數(shù): 4546
    本文關(guān)鍵字:XMLBeansApacheXmlCursorXPathXQueryOpen SourceDev ToolboxXMLJacob Danner開源
    文章工具
    推薦給朋友 推薦給朋友
    打印文章 打印文章

    摘要

      隨著面向服務(wù)架構(gòu)的出現(xiàn),大部分用戶不得不在應(yīng)用程序中使用XML。在開發(fā)過程中,用戶可能已經(jīng)注意到存在多種可以分析和處理XML的模型,包括開源和專有的。所有這些模型都存在一定的優(yōu)缺點。選擇不適合業(yè)務(wù)需求的模型可能會導(dǎo)致開發(fā)時間延長并浪費資源。Apache XMLBeans是一個非常有價值的工具,它提供一種在Java中使用XML的簡便方法。在本文中,我們將介紹XMLBeans以及XMLBeans 2.0中的一些有用特性。

    XMLBeans簡介

      W3C XML Schema是一個XML文檔,該文檔定義一組其他XML文檔必須遵守才合法的規(guī)則。與早期XML模式語言如文檔類型定義(document type definition,DTD)或簡單對象XML(simple object XML,SOX)相比,W3C XML Schema具有許多優(yōu)點,它還提供了可供用戶以多種方式使用的豐富特性集。

      XMLBeans是完全與模式兼容的XML-Java綁定工具,使用這個工具可以以對Java友好的方式訪問XML的全部特性。XMLBean解決方案是獨一無二的,因為它提供XML數(shù)據(jù)的雙重視圖。XMLBeans維護(hù)一個信息和結(jié)構(gòu)均未更改的原始XML文檔,并提供一個基于Java的XML數(shù)據(jù)視圖。

      現(xiàn)在我們通過顯示一些代碼示例來演示XMLBeans 2.0中的一些特性。在每個示例中,我們都會提供模式以及一些操縱模式的XMLBean表示的Java代碼。模式和Java示例都可供下載。

      下面我們來看下面的模式片斷:

       

      1 <xs:element name="order">
    2 <xs:complexType>
    3 <xs:sequence>
    4 <xs:element name="orderNo" type="xs:string"/>
    5 <xs:element name="item" nillable="true"
    6 maxOccurs="unbounded" type="tns:itemType"/>
    7 <xs:element name="address" type="tns:addressType"/>
    8 <xs:element name="quantity" type="tns:quantityType"/>
    10 </xs:sequence>
    11 </xs:complexType>
    12 </xs:element>

      要生成XMLBeans類,需要對模式進(jìn)行編譯。使用scomp實用工具可以很輕松地完成這個任務(wù),因為它可以為所有簡單和復(fù)雜的類型生成接口。所有類和接口的包名均派生自模式中指定的targetNamespace值。詳細(xì)情況請閱讀Hetal Shah的Configuring XMLBeans(中文版,Dev2Dev,2005年3月)。

      現(xiàn)在我們看看如何生成實例文檔,如何針對模式檢查文檔的有效性,以及如何將實例保存到文件系統(tǒng)。

      下面所生成的OrderDocument接口是一個XMLBeans為任意全局元素或類型創(chuàng)建的特殊“文檔”類型示例。

      AddressType和ItemType是為全局復(fù)雜類型addressType和sizeType創(chuàng)建的接口:

       

       1 OrderDocument orderDoc = OrderDocument.Factory.newInstance();
    2 Order order = orderDoc.addNewOrder();
    3 order.setOrderNo("ORD1234");
    4 order.setQuantity(4);
    5
    6 AddressType aType = order.addNewAddress();
    7 aType.setCity("Kirkland");
    8
    9 ItemType iType = order.addNewItem();
    10 iType.setId("ITEM003");
    11
    12 boolean isValid = orderDoc.validate(xopt);
    13
    14 orderDoc.save(new File("sample.xml"),xopt);

      運行此示例會導(dǎo)致構(gòu)建一個實例文檔,該文檔將被驗證并以“sample. xml”為名保存在本地文件系統(tǒng)中。該程序還會將此實例文檔的內(nèi)容以及驗證測試的結(jié)果顯示到命令提示符或Unix shell中:

       

       1 <sam:order xmlns:sam="http://temp.openuri.org/Sample">
    2 <sam:orderNo>ORD1234</sam:orderNo>
    3 <sam:item>
    4 <sam:id>ITEM003</sam:id>
    5 <sam:description>Latest Item</sam:description>
    6 <sam:size>Large</sam:size>
    7 </sam:item>
    8 <sam:address>
    9 <sam:Name>BEA Systems, Inc</sam:Name>
    10 <sam:Street>10230 NE Points Drive, Ste 300</sam:Street>
    11 <sam:City>Kirkland</sam:City>
    12 <sam:Zip>98033</sam:Zip>
    13 <sam:State>WA</sam:State>
    14 <sam:Country>USA</sam:Country>
    15 </sam:address>
    16 <sam:quantity>4</sam:quantity>
    17 </sam:order>

      這是一個有效的實例文檔。在編譯一個模式時,從模式生成的API會與表示底層XML模式的XMLBeans類型系統(tǒng)相集成。對模型相關(guān)信息的訪問權(quán)限可通過使用模式類型系統(tǒng)API獲取。

      在下一個示例中,我們將展示如何使用getEnumerationValues()方法編程式地訪問特定模式類型的多個枚舉值。我們使用的模式類型是sizeType,它是帶有三個可能值的枚舉類型。該模式片斷如下所示:

       

       1 <xs:simpleType name="sizeType">
    2 <xs:restriction base="xs:token">
    3 <xs:enumeration value="Small"/>
    4 <xs:enumeration value="Medium"/>
    5 <xs:enumeration value="Large"/>
    6 </xs:restriction>
    7 </xs:simpleType>

      SizeType是SchemaType類,它包含關(guān)于simpleType模式類型的信息:

      SchemaType schType = null;
    XmlAnySimpleType [] xmlarray = null;
    SizeType sType = SizeType.Factory.newInstance();
    schType = sType.schemaType();
    xmlarray = schType.getEnumerationValues();

      運行此代碼示例(EnumerationSample.java)將導(dǎo)致編程式地獲取枚舉值并將其重定向到System.out:

      Enumeration values for ItemType :
    Small
    Medium
    Large

      XmlCursor是XMLBeans中的一個有趣特性;它們提供一種操作或?qū)Ш絏ML實例文檔的直觀方法。XmlCursor還提供了一種執(zhí)行XQuery表達(dá)式的方法。一旦加載了XML文檔,就可以創(chuàng)建一個游標(biāo)來表示XML中的特定位置。因為用戶可以使用具有或不具有對應(yīng)于XML的模式的游標(biāo),因此游標(biāo)是處理XML的理想方法。

      下一個示例演示如何使用游標(biāo)操作XMLBean實例。此示例分析在第一個示例中創(chuàng)建的sample.xml。一旦將該文件保存到內(nèi)存中,就會使用XmlCursor API導(dǎo)航到quantity元素并將值更改為104:

      orderDoc = OrderDocument.Factory.parse(new File("sample.xml"));
    XmlCursor xcursor = orderDoc.newCursor();
    xcursor.toFirstChild();
    xcursor.toChild(3);
    xcursor.toEndToken();
    xcursor.toPrevChar(1);
    xcursor.insertChars("10");
    xcursor.disp ose();

      運行此示例會生成下面的輸出,它顯示修改后的XMLBean文檔為什么會無效:

      Message: decimal
    value (104) is greater than maxInclusive facet (5) for
    quantityType in namespace http://temp.openuri.org/Sample
    Location of invalid XML:
    <xml-fragment xmlns:sam="http://temp.openuri.org/Sample"/>

      到目前為止,我們已經(jīng)簡要介紹了XMLBeans,現(xiàn)在介紹一下2.0版本中的新特性。

    XMLBeans 2.0中的新特性

      通常,通過觀察產(chǎn)品的實際運行來了解其中的新特性是比較簡便的方法。我們將通過介紹一個利用了XMLBeans的某些重要特性的項目來介紹這些新特性。眾所周知,XMLBeans是一個Apache項目,所以它使用Atlassian的Jira問題跟蹤和項目管理應(yīng)用程序來跟蹤bug、特性和其他問題。BEA對XMLBeans項目進(jìn)行了投資,并擁有一個提供高質(zhì)量軟件的標(biāo)準(zhǔn)。這意味著BEA很關(guān)注XMLBeans之類項目的質(zhì)量。由于XMLBeans是開源項目,并且它使用Apache的常見工具如Jira,所以問題就在于BEA如何跟蹤XMLBeans的質(zhì)量指標(biāo)。

      用于揭示XMLBeans 2.0中的一些新特性的計劃就是對這個問題的回答:如何方便地從Jira收集質(zhì)量指標(biāo)?

      下面的屏幕快照顯示了XMLBeans的項目主頁面。請看圖片的右邊,在Project Summary區(qū)域下可以看到一些與我們關(guān)心的質(zhì)量指標(biāo)問題相關(guān)的選項。

    圖1:XMLBeans Jira項目頁面
    圖1:XMLBeans Jira項目頁面(單擊圖像查看大圖)

      Jira的一個好處就是它能提供問題數(shù)據(jù)的不同視圖。在下圖中,請看名為Current View的標(biāo)題。在屏幕快照中,目前選擇的是Browser視圖,但還有其他選項,包括一個打印視圖、一個XML視圖,甚至還有一個Excel電子表格視圖:

    圖2:XMLBeans Jira Issue Navigator
    圖2:XMLBeans Jira Issue Navigator(單擊圖像查看大圖)

      熟悉Jira以及XMLBeans跟蹤質(zhì)量指標(biāo)的方式后,我們可以通過多種方式收集質(zhì)量指標(biāo)。我們的選項包括屏幕抓取HTML、分析電子表格以及從URL獲取XML。我們認(rèn)為最合理的是從URL(通過從Issue Navigator頁面單擊XML鏈接而提供)使用XML視圖。該URL的內(nèi)容看起來與下面的XML文檔類似:

      <?xml version="1.0" encoding="utf-8" ?>
    <!-- RSS generated by JIRA 98 at Sun Dec 04 18:08:34 CET 2005
    -->
    <rss version="0.92">
    <channel>
    <title>ASF JIRA</title>
    <link>http://issues.apache.org/jira</link>
    <description>This file is an XML representation of some
    issues</description>
    <language>en</language>
    <item>
    <title>[XMLBEANS-232] Fast Xml Infoset</title>
    <link>http://issues.apache.org/jira/browse/x</link>
    <description>
    <!-- left out for brevity -->
    </description>
    <environment><![CDATA[]]></environment>
    <key id="12326193">XMLBEANS-232</key>
    <summary>Fast Xml Infoset</summary>
    <type id="4">Improvement</type>
    <priority id="3">Major</priority>
    <status id="1">Open</status>
    <resolution>Unresolved</resolution>
    <assignee>Unassigned</assignee>
    <reporter username="rrusin">Rafal
    Rusin</reporter>
    <created>Wed, 30 Nov 2005 13:29:44 +0100
    (CET)</created>
    <updated>Sat, 3 Dec 2005 18:15:10 +0100
    (CET)</updated>
    <version>unspecified</version>
    <fixVersion>unspecified</fixVersion>
    <component>XmlObject</component>
    <due></due>
    <votes>0</votes>
    <comments>
    <comment author="dandiep" created="Sat, 3 Dec 2005
    18:15:10 +0100 (CET)" level="">
    <!-- ... -->
    </comment>
    </comments>
    <customfields>
    </customfields>
    </item>
    <item>
    <!-- left out for brevity -->
    </item>
    </channel>
    </rss>

      如果從上面的XML feed查看片斷,會發(fā)現(xiàn)它被定義為RSS feed。我們的第一步是找到一個RSS 0.92版本的XML Schema模式,這樣就可以編譯模式,并通過使用XMLBeans的類似于JavaBean的簡單API來使用XMLBeans分析URL。我們無法找到官方模式,但可以找到規(guī)范,并可由此開始創(chuàng)建模式。隨后,我們發(fā)現(xiàn)根據(jù)規(guī)范創(chuàng)建的模式與從Jira獲取的RSS feed不匹配。我們該怎么做呢?我們實際上惟一可以選擇的就是為此RSS feed創(chuàng)建一個模式,但這費時且容易出錯。進(jìn)行了進(jìn)一步的調(diào)查后,我們偶然發(fā)現(xiàn)了新增的inst2xsd特性。

    模式到實例再到模式的過程

    inst2xsd工具可作為命令行實用工具使用,但用戶也可以編程式地使用API。其目的是采用一個XML實例并創(chuàng)建一個合法模式集。該工具也是可配置的,它提供了用于指定使用哪種設(shè)計模式的選項(包括Russian Doll、Salami Slice、Venetian Blind;詳細(xì)信息請參見模式設(shè)計指導(dǎo)原則)。

      該工具還能夠?qū)⒚杜e映射到重復(fù)值,并能夠根據(jù)數(shù)據(jù)類型的最小公分母創(chuàng)建類型。

      我們使用lcd:val這個值作為創(chuàng)建最小公分母類型的示例。該文本可由多個內(nèi)置XML Schema數(shù)據(jù)類型表示,例如字符串派生的類型(xsd:string、xsd:normalizedString、xsd:token,等等)以及QName類型。在本例中,inst2xsd特性確定類型的方式是查找前綴為lcd的命名空間聲明。如果找到該前綴,該類型將是QName,而不是某個可能基于字符串的類型。

      現(xiàn)在看一下我們從Jira接收的RSS feed的結(jié)果是什么。如果我們已經(jīng)將feed保存到名為jiraRssFeed.xml的實例中并已將XMLBEANS_HOME\bin放在我們的路徑中,工作流將如下:

      /home/user>inst2xsd
    Generates XMLSchema from instance xml documents.
    Usage: inst2xsd [opts] [instance.xml]*
    Options include:
    -design [rd|ss|vb] - XMLSchema design type
    rd - Russian Doll Design - local elements and local types
    ss - Salami Slice Design - global elements and local
    types
    vb - Venetian Blind Design (default) - local elements and
    global complex types
    -simple-content-types [smart|string] - Simple content types
    detection (leaf text). Smart is the default
    -enumerations [never|NUMBER] - Use enumerations. Default
    value is 10.
    -outDir [dir] - Directory for output files. Default is '.'
    -outPrefix [file_name_prefix] - Prefix for output file names.
    Default is 'schema'
    -validate - Validates input instances against generated
    schemas.
    -verbose - print more informational messages
    -license - print license information
    -help - help information

    /home/user>inst2xsd jiraRssFeed.xml -enumerations never
    -design rd -verbose -validate
    # this generates a schema named schema0.xsd

      這將生成名為schema0.xsd的(可配置)文件,并且模式將與下面的片斷類似:

       1 <?xml version="1.0" encoding="UTF-8"?>
    2 <xs:schema attributeFormDefault="unqualified"
    elementFormDefault="qualified"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
    3 <xs:element name="rss">
    4 <xs:annotation>
    5 <xs:documentation>RSS generated by JIRA 98...
    </xs:documentation>
    6 </xs:annotation>
    7 <xs:complexType>
    8 <xs:sequence>
    9 <xs:element name="channel">
    10 <xs:complexType>
    11 <xs:sequence>
    12 <xs:element type="xs:string" name="title"/>
    13 <xs:element type="xs:anyURI" name="link"/>
    14 <xs:element type="xs:string" name="description"/>
    15 <xs:element type="xs:string" name="language"/>
    15 <xs:element name="item" maxOccurs="unbounded"
    minOccurs="0">

      從這個片斷中我們發(fā)現(xiàn)Jira RSS feed所需的所有元素均已定義。

      如果用戶想要通過其他方式工作,例如從XML Schema開始,XMLBeans的最新版本就提供了這種功能。xsd2inst工具就為用戶提供了從模式和全局元素創(chuàng)建示例文檔的方式;該實例將包含簡單類型的值。上述兩種工具的使用使得使用XML實例和模式變得非常簡單。

      在項目的這個階段,我們就擁有了一個模式,使用這個模式可以通過scomp實用工具創(chuàng)建一個XMLBeans類型jar,并可開始處理業(yè)務(wù)邏輯以及先前嘗試收集的質(zhì)量指標(biāo)。

      通過查看Jira RSS feed實例,我們發(fā)現(xiàn)我們關(guān)注的bug詳細(xì)信息放在名為item的元素中,而且生成的模式將item元素作為數(shù)組。這意味著,如果我們想要獲得可能出現(xiàn)在所有項中的信息,就需要迭代所有項。現(xiàn)在我們看看如何通過一些代碼實現(xiàn)這個目標(biāo)。在下面的代碼中,我們會遇到名字被指定為方法參數(shù)的用戶導(dǎo)致的所有問題:

       1 public Vector getItemsFromReporter(String reporter) {
    2
    3 // Get the Jira RSS feed instance from a URL
    4 URL jiraFeedUrl; = new URL("");
    5
    6 // Get instance objects
    7 RssDocument rssDoc = RssDocument.Factory.parse(jiraFeedUrl);
    8 RssDocument.Rss rss = rssDoc.getRss();
    9 RssDocument.Rss.Channel channel = rss.getChannel();
    10
    11 // We will use this object to get most of our data
    12 RssDocument.Rss.Channel.Item[] items = channel.getItemArray();
    13
    14 //We will store all of the valid results in a vector
    15 Vector results = new Vector();
    16
    17 for (int i = 0; i < items.length; i++) {
    18 RssDocument.Rss.Channel.Item item = items[i];
    19
    20 //Add item to results vector when reporter == username
    21 if(item.getReporter().getUsername().compareTo(reporter) == 0)
    22 results.add(item);
    23 }
    24 }
    25
    26 return results;
    27 }

      可以看出,這是非常整潔的Java代碼。但是,當(dāng)項數(shù)變大時,使用此代碼也會影響性能。在最新的XMLBeans版本中,新增了兩個新特性來幫助解決這些問題。第一個特性是對JDK 5.0泛型的支持,第二個特性是對XPath和Xquery的支持。我們來看看如何將泛型用于XMLBeans。

    將泛型用于XMLBeans

      很明顯,JDK 5.0泛型可幫助創(chuàng)建參數(shù)化的類和方法。Collections API是XMLBeans中首批使用泛型的API之一。在XML Schema中,當(dāng)元素包含的maxOccurs屬性的值大于1時,默認(rèn)情況下XMLBeans將針對這些類型創(chuàng)建一個Java數(shù)組。為了啟用泛型,需要將一個附加參數(shù)添加到scomp,并需要使用一個兼容JDK 5.0的虛擬機。

      默認(rèn)情況下,用于從channel獲取item元素的API包含如下方法:

     
    RssDocument.Rss.Channel.Item getItemArray(int i)
    獲取item元素
    RssDocument.Rss.Channel.Item[] getItemArray()
    獲取所有item元素的數(shù)組
    void setItemArray(int i,RssDocument.Rss.Channel.Item item)
    設(shè)置item元素
    void setItemArray(RssDocument.Rss.Channel.Item[] itemArray)
    設(shè)置所有item元素的數(shù)組

      但是,執(zhí)行了啟用泛型的編譯步驟后,API會有所變化:

      /home/user>scomp
    Compiles a schema into XML Bean classes and metadata.
    Usage: scomp [opts] [dirs]* [schema.xsd]* [service.wsdl]*
    [config.xsdconfig]*
    Options include:
    ...
    -javasource [version] - generate java source compatible for a
    Java version (1.4 or 1.5)
    ...

    #This is all it takes to enable Generics in your use of XMLBeans
    /home/user>scomp -javasource 1.5 schema0.xsd

      使用上面的示例,可用的新方法將如下所示:

    java.util.List<RssDocument.Rss.Channel.Item> getItemList
    獲取item元素的列表

      現(xiàn)在我們來看看泛型的使用如何能夠簡化用于實現(xiàn)獲取單個用戶報告的所有項的方法的代碼:

       1 public List getItemsFromReporter(String reporter) {
    2
    3 // We already loaded the data as above
    4 // ...
    5 RssDocument.Rss.Channel channel = rss.getChannel();
    6
    7 // We will use this object to get most of our data
    8 List<RssDocument.Rss.Channel.Item> items =
    channel.getItemList();
    9
    10 for (int i = 0; i < items.size(); i++) {
    11 RssDocument.Rss.Channel.Item item = items.get(i);
    12
    13 //Remove results from list
    14 if (item.getReporter().getUsername().compareTo(reporter)
    != 0)
    15 items.remove(i);
    16 }
    17 }
    18
    19 return items;
    20 }

      這種方法非常不錯,但還有一種更加簡單的獲取每個用戶的項信息的方法——當(dāng)您了解XPath和/或XQuery之后。

    XQuery和XPath

      XMLBeans與XQuery和XPath的集成在2.0版本中有了變化。版本1中使用了Jaxen(一種XPath實現(xiàn)),但與XMLBeans的集成不支持命名空間和前綴。最新版本構(gòu)建于Saxon 8.1.1版本所提供的XQuery實現(xiàn)的基礎(chǔ)之上。由于XQuery在Xpath之上構(gòu)建,所以Saxon還為XMLBeans提供了XPath實現(xiàn)。為了使用XQuery和XPath的特性,XmlObject類(所有XMLBeans類型都派生自它)提供了兩個執(zhí)行實例的查詢和語句的方法。XmlObject API的execQuery()和selectPath()方法返回一個匹配組件的數(shù)組。這些方法在XmlCursor對象上也存在,但返回對象是使用匹配值列表填充的另一個XmlCursor對象:

       1 String xq = "for $e in //employee 
    where $e/name='Bob' return $e ";
    2
    3 // Input is a valid xml instance
    4 XmlObject o = XmlObject.Factory.parse(input);
    5
    6 XmlObject[] xObjres = o.execQuery(xq);
    7 XmlCursor xCurres = o.newCursor.selectPath(xq);

      從上面的代碼片斷中可以看出API相當(dāng)易用,而且您可以采取最方便的方式處理生成的數(shù)據(jù)。我們在第4行中構(gòu)建了自己的查詢語句,并在第6和第7行中使用不同的API運行該查詢。XQuery是一個強大的工具,從下面的代碼中可以看出獲取項數(shù)據(jù)變得多么簡單:

       1 public XmlObject[] getItemsFromReporter(String reporter) {
    2
    3 //Load Jira RSS feed data
    4 URL jiraFeedUrl; = new URL("");
    5
    6 //This is the only object we need
    7 RssDocument rssDoc = RssDocument.Factory.parse(jiraFeedUrl);
    8
    9 //Build the statement for the xpath engine
    10 String xpathStatement =
    "http://item[reporter/@username='"+reporter+"']";
    11
    12 //Execute the statement on the instance
    13 //We could cast this to an Item[] if we wanted
    14 XmlObject[] queryResult = rssDoc.selectPath(xpathStatement);
    15
    16 return queryResult;
    17 }

      將XQuery與XMLBeans同時使用將使其如虎添翼,使對XML的處理變得簡單得多。如果要獲取更多有關(guān)XQuery的信息,有無數(shù)的資源可供參考。我們建議從Apache XMLBeans Web站點上的XMLBeans示例開始。

      到此時,由于XMLBeans提供的最新特性,XMLBeans的質(zhì)量指標(biāo)跟蹤問題解決方案實現(xiàn)起來已經(jīng)非常容易了。我們使用inst2xsd實用工具為實例創(chuàng)建模式,而不用從頭編寫,從而節(jié)省了時間。我們可以看到泛型的啟用如何通過使業(yè)務(wù)邏輯變得容易編寫而提高了生產(chǎn)力。最后,我們看到新增的XQuery集成如何提供操縱和查詢XML的豐富特性。

      這些僅僅是最新版本的XMLBeans中的基本新特性。一些其他特性使得XMLBeans成為可滿足處理XML時的所有開發(fā)需要的理想工具。而下一個特性提供有關(guān)使用XML和XML Schema時可能接收到的錯誤的更詳細(xì)信息,從而幫助開發(fā)人員提高生產(chǎn)力。

    錯誤代碼

      錯誤代碼是2.0版本中提供的另一個偉大特性。人們已創(chuàng)建了許多種方法,以便將這個新特性與scomp之類的工具集成,并允許編程式地訪問以便(比如說)在IDE中使用。XML Schema規(guī)范的附錄C定義了一個錯誤代碼集,它定義了非法模式條款。在分析、驗證和編譯過程中,可使用錯誤監(jiān)聽程序編程式地訪問錯誤代碼。以前,錯誤消息的詳細(xì)信息和模式一致性是越小越好。此外,還添加了有關(guān)錯誤所在位置以及模式規(guī)范中的相關(guān)內(nèi)容的詳細(xì)信息。錯誤代碼本身以“cvc-complex-type.2.2”的形式定義,可參見http://www.w3c.org/TR/xmlschema-1/#cvc-complex-type條款2.2中的解釋。下面我們來看看它的工作方式。我們從一個XML Schema開始,并針對它驗證一個實例。然后我們將查看舊的錯誤,并與接收到的最新版本進(jìn)行比較。

       1 <!-- errorcode.xsd -->
    2 <xs:schema
    3 xmlns:xs="http://www.w3.org/2001/XMLSchema"
    4 targetNamespace="http://xmlbeans.rocks.com/"
    5 xmlns:tns="http://xmlbeans.rocks.com/" >
    6 <xs:element name="address" type="tns:address"/>
    7 <xs:complexType name="address">
    8 <xs:sequence>
    9 <xs:element name="number" type="xs:unsignedInt"/>
    10 <xs:element name="street" type="xs:string"/>
    11 <xs:choice>
    12 <xs:sequence>
    13 <xs:element name="city" type="xs:string"/>
    14 <xs:element name="state" type="xs:string"/>
    15 </xs:sequence>
    16 <xs:element name="zipcode" type="xs:int"/>
    17 </xs:choice>
    18 <xs:element name="country" type="xs:string"/>
    19 </xs:sequence>
    20 </xs:complexType>
    21 </xs:schema>

      這個模式相當(dāng)簡單。注意xs:choice模型組的用法,因為下面的示例正是在對其進(jìn)行定義時出錯的。我們將要介紹一些錯誤代碼,您很快就可以發(fā)現(xiàn)問題所在:

       1 <!-- errorcode.xml -->
    2 <t:address
    3 xmlns:t="http://xmlbeans.rocks.com/" >
    4 <number>72</number>
    5 <street>156th NE</street>
    6 <country>USA</country>
    7 </t:address>

      除了可從命令行使用的scomp實用工具,還存在一個可針對模式驗證實例的實用工具。

      /home/user>validate
    Validates the specified instance against the specified schema.
    Contrast with the svalidate tool, which validates using a stream.
    Usage: validate [-dl] [-nopvr] [-noupa] [-license]
    schema.xsd instance.xml
    Options:
    -dl - permit network downloads for imports and
    includes (default is off)
    -noupa - do not enforce the unique particle attribution rule
    -nopvr - do not enforce the particle valid (restriction) rule
    -partial - allow partial schema type system
    -license - print license information

      如果使用XMLBeans的1.0版本運行validate實用工具,結(jié)果將如下所示:

      /home/user>validate errorcode.xsd errorcode.xml
    errorcode.xml:0: error: Expected elements
    city zipcode at the end of the content in element
    address@http://xmlbeans.rocks.com/

      上面的錯誤文本提到了實例的名稱,并告訴我們地址的末尾缺少一些應(yīng)有的元素。在這個小示例中,這是有點用處的,但沒有行號很難找到起點。現(xiàn)在我們將這個代碼文本與新版本中的新增錯誤代碼特性進(jìn)行比較:

       /home/user>validate errorcode.xsd errorcode.xml

    errorcode.xml:4: error: cvc-complex-type.2.4a: Expected elements
    'city state' instead of 'country' here in element
    address@http://xmlbeans.beaworld.com/

    errorcode.xml:4: error: cvc-complex-type.2.4c: Expected elements
    'zipcode' before the end of the content in element
    address@http://xmlbeans.beaworld.com/

      與XMLBeans的1.0版本中的錯誤文本相比,新的錯誤文本有很大的改進(jìn)。兩個錯誤文本都提到了實例,但新錯誤代碼還提供了行號、問題嚴(yán)重程度、附錄C模式參考以及更清楚的錯誤消息。而且,使用新的錯誤代碼,我們發(fā)現(xiàn)錯誤代碼cvc-complex-type.2.4a和cvc-complex-type.2.4c還提及更多造成故障的問題。同樣,這些錯誤代碼也分別對應(yīng)于模式規(guī)范中一個可使用URL訪問的位置。

      剛剛我們介紹了如何通過命令行獲取詳細(xì)的錯誤文本,現(xiàn)在介紹如何以編程方式獲取錯誤信息:

       1 // Create the error listener and XmlOptions 
    2 LinkedList list = new LinkedList();
    3 XmlOptions opts = new XmlOptions().setErrorListener(list);
    4
    5 // Load the instance
    6 File instance = new File("<SOME_PATH>\errorcodes.xml");
    7 AddressDocument ad = AddressDocument.Factory.parse(instance);
    8
    9 // If there are errors, making a method call like this will
    10 // populate the error listener
    11 ad.validate(opts);
    12
    13 // Since we know there are errors, let's
    14 // look at how to get at the data
    15 for(int i=0; i < errors.size(); i++) {
    16
    17 // Cast list object to an XmlError
    // type XmlError e = (XmlError)
    18 errors.get(i);
    19
    20 // Now, let's get at all the information about the error
    21 // This will be the location of the error in the instance
    22 System.out.println("["+e.getLine()+","+e.getColumn()+"]-" +
    e.getSeverity())
    23 // Information about the error
    24 System.out.println(e.getErrorCode() + ": " +e.getMessage());
    25 }

      請看此代碼片斷,以編程方式訪問錯誤信息并不比從命令行獲取類似信息困難多少。

    性能提升

      用戶可能不會注意到以前的特性,但一定會注意到它對開發(fā)工作的影響。如果新版本無法帶來性能提升,那它還有什么好處呢?

      與在XMLBeans 1.0中一樣,性能對于2.0版本極為重要。在大多數(shù)情況下,與1.0相比,2.0版本性能有了10%到60%的提升。導(dǎo)致性能提升的原因有許多,其中最重要的是完全不同的存儲架構(gòu)。在1.0版本中,使用了一個名為splay tree的數(shù)據(jù)結(jié)構(gòu)使所有存儲在XML Store中的內(nèi)容與影響XML數(shù)據(jù)的操作同步。對于不熟悉它的用戶,splay tree可以理解為支持O(log N)次Find、Insert和Delete操作的平衡樹。這種數(shù)據(jù)結(jié)構(gòu)與其他此類樹的差別在于它不維持顯式的平衡條件。其詳細(xì)程度超出了用戶在大多數(shù)情況下的需要。2.0版本使用了一個較為簡單的架構(gòu),提供較少的復(fù)制和較少的對象。

      在對XML數(shù)據(jù)執(zhí)行任何操作時,XMLBeans都會加載一個XML Store。XMLBeans總是加載一個XML Store,然后在Store上提供一個綁定視圖。與直接解組到Java對象的其他Java/XML綁定框架相比,此綁定視圖與完整的XML Infoset真實性通常導(dǎo)致額外的開銷。這使得XMLBeans的性能一直是一個障礙,從而消弱了額外的特性與信息所帶來的好處。對于運行時性能,人們主要關(guān)注的就是XML Store方面,并盡可能地使Store的性能得到提高。

      在對XML Store進(jìn)行改寫時,新增了一個特性,該特性使得使用XMLBeans進(jìn)行編程可以有更好的性能,并且更易于使用。此特性即DOM Level II支持。DOM是Document Object Model(文檔對象模型)的簡寫,它提供了一個用于處理XML數(shù)據(jù)的接口。Level II則指定哪些接口是可用的。它與SAX的區(qū)別在于XML信息保存在內(nèi)存中。

    固有的DOM II支持

      在1.0版本中,對DOM的訪問由Xerces處理,因此此類調(diào)用返回一個Xerces DOM Node。在2.0中,類似調(diào)用返回XMLBeans DOM表示,因為DOM II現(xiàn)在是天然實現(xiàn)的。這意味著在XMLBeans內(nèi)無需協(xié)調(diào)兩種不同的數(shù)據(jù)存儲即可訪問DOM表示和XMLBeans表示。

      這還意味著可以通過以下三種方式中的任何一種來處理XML。第一種方式是使用XmlObject API中JavaBean風(fēng)格的方法。第二種方式是通過XMLCursor API使用基于令牌的模型。而第三種方式是使用對熟悉DOM API的人來說非常熟悉的樹模型。它有一個特別的好處,就是用戶可以在這些方法之間來回切換,而不必?fù)?dān)心實例的同步問題。從開發(fā)人員的角度來看,這就意味著他們可以使用最順手的方式來處理XML。現(xiàn)在我們來了解一些可以在其中進(jìn)行切換以便獲得XML的底層視圖的API:

      //To get the live DOM Node:
    Node XmlObject.getDomNode()
    Node XmlCursor.getDomNode()

    //To get back:
    XmlObject XmlBeans.nodeToObject(Node n)
    XmlCursor XmlBeans.nodeToCursor(Node n)

    //XMLBeans 1.0 API returns a copy:
    Node XmlObject.newDomNode()

      從上面的代碼中可以看出,在這些視圖之間進(jìn)行切換相當(dāng)容易。

    結(jié)束語

      本文介紹了XMLBeans 2.0中可用的一些新特性。我們了解到XMLBeans提供了一個健壯且完全保真的Java到XML的綁定框架。我們還介紹了如何使用XMLBeans 2.0的一些新特性更方便快捷地完成項目。這些新特性可以提高開發(fā)人員的生產(chǎn)力。性能提升也有助于提高生產(chǎn)力,但更重要的是,這意味著花在對應(yīng)用程序進(jìn)行調(diào)試和分析瓶頸上的時間將會減少。

      我們介紹的特性只是XMLBeans的最新版本所提供的一部分增強。請了解一下XMLBeans,看它是如何幫助改進(jìn)開發(fā)人員的開發(fā)工作的。

    參考資料

    原文出處:http://dev2dev.bea.com/pub/a/2006/05/xmlbeans-2.html

     作者簡介

    Jacob Danner 是BEA的高級軟件工程師。他自2001年BEA的WebLogic Workshop團(tuán)隊建立時起就一直在其中工作。他還曾參與BEA的多項開源工作。

    Raj Alagumalai 是BEA Systems的WebLogic Workshop支持部門的一名高級開發(fā)人員關(guān)系工程師。

    posted on 2008-03-10 17:59 jinfeng_wang 閱讀(775) 評論(0)  編輯  收藏

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


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 99久久久国产精品免费牛牛| 亚洲人成电影网站| www一区二区www免费| 国产精品久久久久影院免费| 精品女同一区二区三区免费播放| 亚洲第一视频在线观看免费| 久久狠狠躁免费观看2020| 亚洲国产精品网站久久| 亚洲精品国产福利一二区| 最近中文字幕2019高清免费| 亚洲国产精品无码中文lv| 亚洲熟女一区二区三区| 日韩精品成人无码专区免费| 色婷婷综合缴情综免费观看| 亚洲精品韩国美女在线| 亚洲精品国产高清不卡在线| 免费h视频在线观看| 国产成人亚洲影院在线观看| 2022年亚洲午夜一区二区福利 | 最近免费中文字幕视频高清在线看| 久久精品国产亚洲av麻| 色天使亚洲综合一区二区| 国产免费怕怕免费视频观看| 香蕉视频在线观看亚洲| 一级做a免费视频观看网站| 免费在线看v网址| 亚洲高清中文字幕综合网| 久久精品免费大片国产大片| 免费高清av一区二区三区| 亚洲熟女乱色一区二区三区 | 亚洲免费网站观看视频| 亚洲综合图色40p| 香蕉免费一区二区三区| 精品亚洲综合久久中文字幕| 国产一区二区三区亚洲综合| 噼里啪啦免费观看高清动漫4| 在线亚洲高清揄拍自拍一品区| 国产成人免费网站| 国产高清对白在线观看免费91| 亚洲精品99久久久久中文字幕| 国产一级黄片儿免费看|