`
holdbelief
  • 浏览: 705875 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

使用 XMLBeans 进行编程

阅读更多
 
深入考察 XMLBeans 的特性和功能。本文通过一个简单的例子介绍 XMLBeans 技术,然后一步一步地介绍编译和绑定的过程,讨论 XML 游标、标记和 XQuery 表达式等高级特性。本文还将讨论 XMLBeans 与其他 XML-Java 数据绑定技术相比所具有的优点。

 

    随着企业应用程序的复杂性不断加剧,XML 文档的约束和规则变得越来越严格。此外,随着业界越来越迅速地采用 Web 服务,XML 开始成为跨越多种平台的不可忽视的重要角色。所有这一切意味着,应用程序迫切需要一种简单而强大的机制来处理 XML。

    XMLBeans 提供了这样一种机制,可以将 XMLBeans 用于 XML 数据绑定。与其他只支持 W3C XML Schema 规范的某个子集的数据绑定技术不同,XMLBeans 支持完整的规范,从这方面来说,它非常强大。对于习惯于面向对象操作的开发人员来说,它还惊人地易用。

    通过 XMLBeans,您可以使用 Java 类访问和操纵 XML 文档中包含的数据。

    它是如何做到这些的呢?实际上,它包括两个步骤:

    XMLBeans 编译器生成XML 模式的对象表示。这种对象表示是一组普通的 Java 类和接口,用于表示模式的结构和约束。

    符合上述模式的实际 XML 实例文档被绑定到 第 1 步生成的 Java 类和接口的实例。绑定过程需要使用 XMLBeans API,以面向对象的方式访问真正的 XML 实例文档中的数据。

    一旦 XMLBeans 编译器生成了和模式对应的一般 Java 类和接口,任何符合该模式的 XML 实例文档都可以使用这些类和接口绑定。XMLBeans 比传统的解析更进了一步,因为用户不再需要进行以下操作:

    导航内存中的数据树中的每个节点。

    编写回调方法,从 XML 文档中提取信息。(关于 XMLBeans 和解析的比较,请参阅本文后面的 XMLBeans 的优点。)

    一个简单的例子

    这是一个简单的例子:输入一个模式,XMLBeans 编译器会将其编译成通用的接口。然后我会向您展示如何将符合该模式的具体 XML 文档实例绑定到这些接口。

    清单 1. 输入模式(automobile-policy.xsd)

   

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="automobile-policy">
   <xs:complexType>
     <xs:sequence>
      <xs:element name="insurance-date" type="xs:dateTime"/>
      <xs:element name="policyholder-information"
            type="policyholder-information" minOccurs="1"/>
      <xs:element name="insured-vehicle"
            type="insured-vehicle" minOccurs="1"/>
      <xs:element name="liability-coverage"
            type="liability-coverage" minOccurs="1"/>
      <xs:element name="third-party-coverage"
            type="third-party-coverage"/>
     </xs:sequence>
   </xs:complexType>
  </xs:element>
  <xs:complexType name="policyholder-information">
   <xs:sequence>
     <xs:element name="name" type="xs:string"/>
     <xs:element name="social-security-number" type="xs:string"/>
     <xs:element name="address" type="xs:string"/>
   </xs:sequence>
  </xs:complexType>
  <xs:complexType name="insured-vehicle">
   <xs:sequence>
   <xs:element name="year-of-manufacture" type="xs:string"/>
     <xs:element name="make" type="xs:string"/>
     <xs:element name="model" type="xs:string"/>
     <xs:element name="price" type="xs:double"/>
   </xs:sequence>
  </xs:complexType>
  <xs:complexType name="liability-coverage">
   <xs:sequence>
     <xs:element name="coverage-limit" type="xs:double"/>
     <xs:element name="coverage-premium" type="xs:double"/>
   </xs:sequence>
  </xs:complexType>
  <xs:complexType name="third-party-coverage">
   <xs:sequence>
     <xs:element name="coverage-limit" type="xs:double"/>
     <xs:element name="coverage-premium" type="xs:double"/>
   </xs:sequence>
  </xs:complexType>
</xs:schema> 

    清单 1中的模式描述的是一种汽车保险单,其中包括:

    名为 automobile-policy 的全局根元素。

    4 种复杂类型: policyholder-information 、 insured-vehicle 、 liability-coverage 和 third-party-coverage 。

    一种简单类型 insurance-date 。

   

    编译过程

    在进入 清单 1所示模式的编译过程之前,请下载并安装 Apache XMLBeans version 1.03(请参阅 Resources)。释放压缩包中的文件,将 bin 目录放到 path 下,并将 lib/xbean.jar 放到 classpath 中。

    bin 目录中包含执行一些有用动作的脚本,比如(在 Windows 平台上):

    scomp.cmd 是将模式编译成 XMLBeans 类和接口的模式编译器。

    validate.cmd 对模式验证 XML 实例文档。

    对于 UNIX 和 Linux 平台,XMLBeans 提供了 scomp.sh 和 validate.sh 来执行上述操作。

    xbean.jar 包含真正的 XMLBeans API 类。

    将模式放在适当的文件夹中并设置好 path 与 classpath ,使用 下面的命令编译模式:

   

scomp -out automobile-policy.jar automobile-policy.xsd

    在上述命令中, scomp 是模式编译器, -out 选项用于命名输出的 jar 文件,这里使用的 automobile-policy.jar ; automobile-policy.xsd 是编译的模式。 

    上述命令将 automobile-policy.xsd 编译成 XMLBeans 接口和类,并将它们打包到 automobile-policy.jar 。编译后将生成以下接口: 

    AutomobilePolicyDocument ,表示文档元素,该元素是由全局根元素生成的,在该例中是 automobile-policy 。       

    AutomobilePolicyDocument$AutomobilePolicy ,表示全局根元素 automobile-policy 。

    PolicyholderInformation ,表示复杂类型 policyholder-information 。

    InsuredVehicle ,表示复杂类型 insured-vehicle 。

    LiabilityCoverage ,表示复杂类型 liability-coverage 。

    ThirdPartyCoverage ,表示复杂类型 third-party-coverage 。

    生成的接口包名是从模式中使用名称空间衍生出来的。因为该模式没有包含名称空间,所以这些接口将被放在包 noNamespace 中。

    让我们看一看这些接口。 AutomobilePolicyDocument 接口包含以下方法:

    getAutomobilePolicy() ,访问 automobile-policy 元素。

    setAutomobilePolicy(AutomobilePolicy automobilePolicy) ,设置 automobile-policy 元素。

    addNewAutomobilePolicy() ,添加 automobile-policy 并返回新的空元素。

    与此类似, AutomobilePolicyDocument$AutomobilePolicy 接口也包含以下方法:

    getPolicyholderInformation() ,访问 policyholder-information 元素。

    getInsuredVehicle() ,访问 insured-vehicle 元素。

    其中的关键是将 XML Schema 结构作为 Java 接口复制,所有的基本操作,即添加新元素以及访问、设置已有的元素,都是作为这些接口的方法来实现的。

    此外,所有生成的接口都有一个包含静态方法的工厂类,比如:

    newInstance() 创建了这种类型的新实例。

    parse() 用于解析真正的 XML 实例文档。

    绑定过程

    将模式编译成 XMLBeans 接口和类之后,需要将 XML 实例绑定到这些类。下面的代码取自 AutomobilePolicyHandler.java ,它使用生成的接口,根据编译后的模式处理真正的 XML 实例。

    清单 2. AutomobilePolicyHandler.java

   

import noNamespace.*;
import java.io.File;
import java.util.Calendar;
public class AutomobilePolicyHandler{
 public static void main(String args[]) {
 try {
  String filePath = "automobile-policy.xml";
  java.io.File inputXMLFile = new java.io.File(filePath);
  AutomobilePolicyDocument autoPolicyDoc =
   AutomobilePolicyDocument.Factory.parse(inputXMLFile);
  AutomobilePolicyDocument.AutomobilePolicy autoPolicyElement =
   autoPolicyDoc.getAutomobilePolicy();
  System.out.println("date is " + autoPolicyElement.getInsuranceDate());
 } catch (Exception e) {
  e.printStackTrace();
 }
 }
}

    清单 2 的代码接受输入的 XML 实例,并使用 AutomobilePolicyDocument Factory 类的 parse() 方法获得 AutomobilePolicyDocument 实例。  

    上述 AutomobilePolicyDocument 实例的 getAutomobilePolicy() 方法可以提供根元素 automobile-policy 的句柄。您可以使用简单的 getter 和 setter 检索 XML 中子元素的值。

    下面的 XML 文件 automobile-policy.xml 符合模式 automobile-policy.xsd ,可以将它用于 清单 2中的方法。

    清单 3. automobile-policy.xml

<automobile-policy>
   <insurance-date>2004-09-05T14:12:22-05:00</insurance-date>
   <policyholder-information>
     <name>Alan</name>
     <social-security-number>1GBL7D1G3GV100770
           </social-security-number>
     <address>171 Dormonth Street, Fairfield, OH</address>
   </policyholder-information>
   <insured-vehicle>
     <year-of-manufacture>1999</year-of-manufacture>
     <make>Chevy</make>
     <model>Optra</model>
     <price>1234</price>
   </insured-vehicle>
   <liability-coverage>
     <coverage-limit>1222</coverage-limit>
     <coverage-premium>12</coverage-premium>
   </liability-coverage>
   <third-party-coverage>
      <coverage-limit>2343</coverage-limit>
      <coverage-premium>14</coverage-premium>
   </third-party-coverage>
  </automobile-policy>

 

    XMLBeans 的层次结构

 

    编译生成的所有 XMLBeans 类都是从 org.apache.xmlbeans.XmlObject 派生的。这是所有 XMLBeans 类型的基本接口,包含一些所有 XMLBeans 类都提供的通用设施:

    有一个从标准 DOM 树或者 SAX 流复制 XMLObject 实例的方法。

    有一个 validate() 方法,可以用它验证该 XMLObject 下的 XML 子树。

    有一个 selectPath(java.lang.String) 方法,该方法使用相对 XPath 查找 XmlObject 子树下的其他 XmlObject 。

    在 XMLObject 层内,有用户驱动的模式类型和内置模式类型。我已经说明了用户驱动类型(如 automobile-policy 和 policyholder-information )的语义。如前所述,每个用户驱动的模式类型都被表示成一个接口。

    另一方面,对于 xs:int 和 xs:string 这类内置模式类型,XMLBeans 提供了 46 种 Java 类型,对应于 W3C XML Schema 规范定义的 46 种内置类型。比如,为了对应 XML Schema 中的 xs:string ,XMLBeans 提供了 XmlString 。

    让我们再回到模式,为了提取 policyholder-information 复杂类型中的 xs:string 类型的社会安全号,XMLBeans 提供了以下方法:

org.apache.xmlbeans.XmlString xgetSocialSecurityNumber();

    该方法返回 XmlString 。 

    当然,XMLBeans 也提供了返回纯 Java 类型的方法:

java.lang.String getSocialSecurityNumber();

    注意,在返回 XMLBeans 类型的情况下,方法名是以 xget 开头的。 xget 版本的方法在性能上要好于 get 版本,因为 get 需要将数据转化成最适当的 Java 类型。  

 

    高级特性

   

    通过这个简单的例子,您已经发现使用 XMLBeans 是多么容易,而且也熟悉了 XMLBeans 的层次结构,现在来看一看 XMLBeans 的一些高级特性。这些特性才真正代表了 XMLBeans 的强大功能。

    XML 游标

    XML 游标定义了 XML 文档中的一个位置。它最适合没有可用模式的 XML 文档。游标允许用户通过改变自身的位置来遍历整个文档,还允许用户删除和插入 XML 片段,访问和设置 XML 值等。

    清单 4 是一个简单的例子,说明了 XML 游标的用法。 CursorHandler.java 中的代码将检索 automobile-policy.xml 中已保险汽车的型号。

    清单 4. CursorHandler.java

 import noNamespace.*;
 import java.io.File;
 import java.util.Calendar;
 import org.apache.xmlbeans.XmlCursor;
 public class CursorHandler {
  public static void main(String args[]) {
  try {
   String filePath = "automobile-policy.xml";
   java.io.File inputXMLFile = new java.io.File(filePath);
   AutomobilePolicyDocument autoPolicyDoc =
     AutomobilePolicyDocument.Factory.parse(inputXMLFile);
   XmlCursor cursor = autoPolicyDoc.newCursor();
   cursor.toFirstContentToken();
   cursor.toChild(2);
   cursor.toChild(2);
   System.out.println(cursor.getTextValue());
   System.out.println("Type of Token is: " +
     cursor.currentTokenType() +
   "nText of Token is" + cursor.xmlText());
   cursor.dispose();
  } catch (Exception e) {
   e.printStackTrace();
  }
  }
 }

    该例中的游标被定义在 XML 实例的开头。方法 toFirstContentToken() 将游标移动到当前 START 或 STARTDOC 内容中的第一个标志上。从本质上说,这意味着将游标移到了根元素 automobile-policy 的起始位置上。  

    因此, cursor.getTextValue() 将打印 XML 文档的全部内容。

    因为我们的目的是查找已保险汽车的型号, cursor.toChild(2) 方法将游标移动到 automobile-policy 的第三个子元素,即 <insured-vehicle> 。现在游标移到了 <insured-vehicle> 元素上,再次调用 cursor.toChild(2) 方法可以将游标移动到相对于当前位置的第三个子元素上,即 <model> 元素。

    然后用方法 cursor.getTextValue() 检索型号值。

    在完成游标的使用之后,不要忘记调用其 dispose() 方法。

   

    XML 标志

 

    XML 标志代表一类 XML 标记。实际上,XML 标志代表了 XML 文档能够包含的不同类型的部分。其中包括 XML 文档的开始和结束、属性和属性值等。

    在代码中移动 XML 游标时,可以将它从一个标志移动到另一个标志。当您移动游标时,是将它移动到符合要求的标志。如果游标没有发现可以移动到的适当标志,那么它将保留在原位,并返回“false”表示游标没有移动。

    每种标志类型都用 TokenType 类中的一个常数表示,其中包括:

    INT_STARTDOC ,表示 XML 文档的开始(不含 XML 声明)。

    INT_ENDDOC ,表示 XML 文档的结束。

    INT_TEXT ,表示元素的内容。

    标志本身不作为对象公开,但其类型和属性可以通过游标方法来访问。比如, CursorHandler.java 中的下列代码片段将打印标志类型和标志值。

    清单 5. 打印标志类型和标志文本的代码

System.out.println("Type of Token is: " + cursor.currentTokenType()
            + "nText of Token is" + cursor.xmlText());

 

    XQuery 表达式

 

    XMLBeans 支持 XQuery 表达式。这种类 SQL 语法能够遍历 XML 文档来访问元素和属性。XQuery 表达式和 XML 游标的结合大大增强了 XQuery 的能力。我们仍然使用上述从 automobile-policy.xml 中检索已保险车辆型号的例子,清单 6 中的代码片段就能够完成这项工作。

    清单 6. 使用 XQuery 表达式 检索 XML 元素值的代码

XmlCursor cursor = autoPolicyDoc.newCursor();
String modelQuery = $this/automobile-policy/insured-vehicle/model;
//Note that execQuery creates a new cursor
XMLCursor resultCursor = cursor.execQuery(modelQuery);
System.out.println(resultCursor.getTextValue());

    清单 6 中的代码创建了一个到达所需元素的 XQuery 表达式。 execQuery() 方法运行该查询表达式,并返回新的 resultCursor 。然后使用该 resultCursor 打印 model 元素的值。变量 $this 表示 XML 游标的当前位置。

 

    XMLBeans 的优点

 

    XMLBeans 面临着传统解析和绑定技术的竞争,如 DOM、SAX、JAXB 和 Castor,但 XMLBeans 有一些独到之处。它们的比较如下:

    DOM 在内容中生成整个文档的树。如果文档非常大,DOM 就会变得对内存非常敏感,并会显著降低性能。通过增量解组(incremental unmarshalling)并提供 xget 方法来访问内置的模式数据类型,XMLBeans 取得了较好的性能。

    与 DOM 相比,SAX 对内存要求不高,但是 SAX 要求开发人员为事件处理程序编写回调方法,而 XMLBeans 则不需要。

    与 XMLBeans 类似,JAXB 和 Castor 也都是 XML/Java 绑定技术,但它们都没有提供百分之百的模式支持。XMLBeans 最大的优势之一是几乎百分之百的支持 XML Schema。此外,XMLBeans 还能够访问完整的 XML Infoset,对于强调元素顺序或者注释的应用程序,这一点特别有用。

 

    XMLBeans 还提供了解析 XML 实例的即时验证。

  XMLBeans 包括一些创新的特性,如 XML 游标和对 XQuery 的支持。

  结束语

  在 XML 和 Java 技术的发展前沿地带,各种各样的技术互相拥挤碰撞着,XMLBeans 在非常短的时间内站稳了脚跟。如果开发人员需要处理复杂的 XML 模式和需要更多的本机支持(比如访问完整的 XML Infoset),那么 XMLBeans 是无可替代的。

  性能的优势和即时验证支持,使 XMLBeans 成为用于各种 XML 和 Java 数据绑定场景的一种非常强大的工具。易于理解的 API 降低了开发人员的学习难度,也使其成为非常诱人的选择。这是一项强大而激动人心的技术。

分享到:
评论

相关推荐

    xmlbeans-2.6.0.zip

    使用 XMLBeans 可以将 Java™ 编程语言与 XML 结合使用。Java 编程语言是一种面向对象的语言,它基于开放的、公开的标准,可移植、健壮而且可靠。由于具备这些特点,Java 编程语言已被广泛接受并在包括娱乐业在内的...

    xmlbeans

    1. **Schema编译**:首先,你需要使用XMLBeans的`scomp`工具对XML Schema进行编译,生成对应的Java源代码。这些源代码将包含所有Schema定义的类型和元素。 2. **对象与XML之间的转换**:一旦Schema编译完成,你可以...

    XMLBEANS的使用总结[调试笔记]

    XMLBEANS是一个强大的Java库,它允许开发人员将XML文档与Java对象进行绑定,从而方便地在XML数据和Java应用程序之间进行交互。这个库基于XML Schema(XSD),提供了对XML的强大支持,包括解析、创建、操作和序列化...

    xmlbeans demo

    在“xmlbeans demo”这个主题中,我们主要关注的是如何使用XMLBeans库来处理基于XML Schema的XML数据。首先,你需要有一个XML Schema文件,它定义了XML文档的结构和约束。例如,如果你有一个名为`mySchema.xsd`的XML...

    xmlbeans 源码

    XMLBeans是Apache软件基金...通过对XMLBeans源码的学习,开发者可以更好地理解XML在Java应用程序中的使用,以及如何利用XMLBeans进行高效的XML处理。同时,这也为自定义XML处理逻辑或者扩展XMLBeans的功能提供了基础。

    xmlbeans2.6.0

    4. **Java编程**:所有操作都在Java环境中进行,使用Java API来处理XML和Excel文件。 5. **JAR包依赖**:在Java项目中,XMLBeans-2.6.0.jar是必需的依赖,用于提供处理XML的API。 在实际开发中,当需要使用Apache ...

    xmlbeans的jar包

    XMLBeans是Apache软件基金会开发的一个Java库,它提供了一种方式来处理XML文档,通过将XML Schema转换为Java类,使开发者能够以面向对象的方式与XML数据进行交互。这个库包含多个组件,如`jsr173_1.0_api.jar`、`...

    xmlbeans 2.3.0

    XMLBeans 2.3.0是该库的一个版本,提供了对XML Schema的全面支持,使开发人员能够直接与符合XML Schema标准的XML文档进行交互。 XMLBeans的核心功能在于其基于Schema的编译过程。当使用XMLBeans时,首先需要为XML ...

    xmlbeans-2.5.0

    - **加载Schema**:使用XMLBeans的工具或者编程方式,将XML Schema文件转换为Java源代码或编译好的类。 - **创建XMLContext**:根据Schema信息创建XMLContext实例,这是使用XMLBeans的起点。 - **操作XML**:利用...

    论文研究-XMLBEANS简化Java对XML编程的应用研究 .pdf

    XMLBEANS简化Java对XML编程的应用研究,刘永环,,XMLBeans是把java类和xml 文档实例进行绑定的一种技术。XMLBean提供了很多种方法操纵XML,其中主要包括JavaBeans 、XML Cursor、XQuery。本文首先��

    XmlBeans学习

    进行编程(下)”这两篇文章则详细阐述了XmlBeans的高级编程技术。开发者可以学习如何使用XPath表达式来查询XML文档中的特定节点,以及如何进行XML数据的验证。此外,还可能涉及到了序列化和反序列化的概念,即将...

    xmlbeans2.6.0.jar.zip

    4. **API灵活性**:XMLBeans提供了多种API,包括StAX(Streaming API for XML)、DOM(Document Object Model)和JAXB(Java Architecture for XML Binding)风格的接口,以适应不同的编程需求。 5. **Excel支持**...

    XML、Java 与 XMLBeans 结合应用的商业价值

    通过使用XMLBeans,开发人员可以快速构建功能丰富的应用,同时确保数据的一致性和完整性。 总结起来,XML、Java与XMLBeans的结合提供了强大的工具集,使得娱乐业以及其他领域的企业能够利用SOA的优势,解决复杂的...

    xmlbeans 2.0

    在使用XMLBeans 2.0时,开发者需要注意它可能不包含最新的XML Schema特性或性能改进,因此对于新项目,可能会考虑使用更新的XML处理库。然而,对于那些依赖XMLBeans 2.0的旧项目,了解并熟练掌握它的特性和用法至关...

    xmlbeans:ClassCastException解决方案(带测试案例)

    综上所述,解决XMLBeans中的`ClassCastException`需要对XML Schema、命名空间和类型安全编程有深入理解。通过合理使用命名空间、类型安全的访问方式,以及编写充分的测试用例,我们可以有效地避免这类问题的发生。在...

    xmlbeans-2.4.0 生成JAVA代码BAT文件

    在实际开发中,XMLBeans可以提高处理XML数据的效率,因为它提供了类型安全的接口,减少了错误的可能性,并且可以直接利用Java的面向对象特性进行编程。然而,它也有一些局限性,例如对复杂XML Schema的支持可能不如...

    xmlbeans.jar

    这个库的核心概念是它允许开发者通过使用标准的Java编程接口(API)来处理XML,而无需直接操作DOM(文档对象模型)或SAX(简单API for XML)。XMLBeans的使用极大地简化了XML数据的处理,特别是在大型项目中,如Web ...

Global site tag (gtag.js) - Google Analytics