XmlBeans的使用

一 下载XmlBeans,下载地址http://www.apache.org/dyn/closer.cgi/xmlbeans/,解压后配置环境变量:

a) 在新建环境变量中加入             XMLBEANS_HOME = C:/xmlbeans-2.3.0
b) 在环境变量PATH中加入           %XMLBEANS_HOME%/bin
c) 在环境变量classpath中加入     %XMLBEANS_HOME%/lib

 

 

二 如果使用eclipse,jbuilder 工具,建立新的工程,建立src,classes,lib 等目录,将解压后的目录下的/lib/xbean.jar,/lib/jsr173_1.0.jar , /lib/resolver.jar 加入工程的build path

 

 

三 执行scomp,scomp工具是生成类的工具,语法格式如下

scomp [options] [dirs]* [schemaFile.xsd]* [service.wsdl]* [config.xsdconfig]*

几个重要的[dirs]*参数如下

-src [dir] 生成的类文件存放的目录 如 D:/project/other-code/xmlbeansTest/src

-out [dir] 生成的jar文件存放的目录 如 D:/project/other-code/xmlbeansTest/lib/xmlbeanscatalog.jar

-compiler [dir] java编译器目录 如 D:/tools/jbx/jdk1.4/bin/javac

[schemaFile.xsd]*  xsd文件的路径 如 D:/xmlbeans-2.1.0/samples/XsdConfig/schemas/catalog.xsd,如果没有xml,xsd,xsdconfig文件,而为了测试用,可以使用xmlbeans下载包中自带的文件,三个文件都有的如【zip】/samples/XsdConfig/,可以此目录下找到

[config.xsdconfig]* xsdconfig 文件用来指定生成的类文件的文件名和方法名等的生成规范等。如 D:/xmlbeans-2.1.0/samples/XsdConfig/schemas/myconfig.xsdconfig

 

实例:当前目录下>scomp -out runreport.jar runreport.xsd -compiler %JAVA_HOME%/bin/javac runreport.xsdconfig

       CMD初始下>scomp  -out D:/Temporary/esri_xmlbeans.jar -compiler %JAVA_HOME%/bin/javac D:/Temporary/ESRI.xsd D:/Temporary/runreport.xsdconfig

 

 

四 配置.xsdconfig文件 

<xb:config xmlns:xb=
"http://xml.apache.org/xmlbeans/2004/02/xbean/config"
>
<xb:namespace uri="##any">

  <xb:package>com.wm.biz.report.xmlbean.runreport</xb:package> 
  <xb:suffix>XmlBean</xb:suffix>
  <xb:prefix>pre</xb:prefix>
</xb:namespace>
</xb:config>

prefix和suffix元素分别指定了从名称空间中为模式类型创建的XMLBeans类名的前缀和后缀,其中名称空间由namespace元素中的uri属性值定义。在以上localInfo.xsdconfig列表中,我们希望不论模式类型代表什么名称空间,都为所有从XML模式创建的XMLBeans类名添加前缀“XmlBean”。为此示例,我们不使用前缀功能。
下一步是创建一个代表localInfo.xsd的一组XMLBeans类。在从示例存档提取文件的工作目录中提示处,输入下列行:

scomp -out localinfo_XmlBeans.jar localInfo.xsd localInfo.xsdconfig  使用配置文件的结果是,生成的XMLBean类将具有适当的后缀。例如,为Zipcode属性生成的XMLBean将被称作ZipcodeAttributeXmlBean.java,而不是原来默认情况下的ZipcodeAttribute。

XML到Java名映射和名称空间URI到包名映射
  XMLBeans具有将XML名映射为Java名称和将名称空间URI映射为Java包名称的配置能力。这允许开发人员在XML名称或名称空间URI改变的情况下,避免重写Java代码,从而使其基于XMLBeans的应用程序更具灵活性。
  作为一个示例,考虑以下配置文件,它为创建模式时我们所使用的每一个名称空间都分配了一个包名称:

<xb:config
 xmlns:xb=
 "http://xml.apache.org/xmlbeans/2004/02/xbean/config"
xmlns:NS1="http://www.helloWeather.com/weather">

...

<xb:namespace uri="http://www.localInfo.com/LI">
  <xb:package>com.localInfo</xb:package>
</xb:namespace>

<xb:namespace uri="http://www.helloWeather.com/weather">
  <xb:package>com.weather</xb:package>
</xb:namespace>

<xb:qname name="NS1:image" javaname="MapXmlBean"/>
...
</xb:config>
  记得要为使用的名称空间声明前缀来使元素成为配置文件中的一部分。这里我们已经为config元素中的http://www.helloWeather.com/weather名称空间声明了前缀NS1。
从该示例可以看出,namespace和package元素用于将名称空间URI映射为应当生成的Java包名称。下面的namespace元素将http://www.localInfo.com/LI名称空间映射为包名com.localInfo。

<xb:namespace uri="http://www.localInfo.com/LI">
  <xb:package>com.localInfo</xb:package>
</xb:namespace>
  这样使用的结果是,为模式类型生成的、属于http://www.localInfo.com/LI名称空间的XMLBean类的包名称是com.localInfo,而不是原来默认情况下的com.localInfo.li。
qname元素用于将模式类型名映射为生成的相应的XMLBeans Java类名称。Qname元素的Name属性对于模式类型是限定的名称,同时javaname属性值代表了相应的生成的XMLBeans类名。
  在weather.xsd中声明的image元素代表了一个位置的映射。在前面的示例中我们使用qname扩展名来将image元素映射为名为MapXmlBean的Java类,使image元素的Java名更加直观。注意:qname比namespace具有更高优先权,所以Java名称指定为MapXmlBean而不只是Map,这样就能与其他XMLBeans类名具有一致性。

接口扩展
  接口扩展功能对于用和它代表的模式类型的结构和属性无关的方法来扩展XMLBean很有用。例如,具有天气状况细节的XML文档中的温度数据用华氏温度表示,但是一些使用相应XMLBeans的客户端应用程序需要摄氏温度表示的数据来作进一步处理。使用接口扩展功能,能将一个转换函数float getTemperatureInCelsius()添加到XMLBean中,它将华氏温度数据转换为摄氏温度。

这里是使用extension元素来完成此功能的配置文件的代码摘录:

<xb:extension for=
"com.weather.LocalWeatherDocumentXmlBean"
>
 <xb:interface
     name="com.extension.weatherExtension">
  <xb:staticHandler>
  com.extension.weatherExtensionHandler
  </xb:staticHandler>
 </xb:interface>
</xb:extension>
  for属性能够接收按空间划分的XMLBeans Java接口列表,或者使用“*”来包含扩展中的所有接口。这种做法的结果是,生成的XMLBeans接口LocalWeatherDocumentXmlBean将扩展指定的接口,在本例中将扩展为com.extension.weatherExtension。该例中,我们为接口声明了两种方法:

public interface weatherExtension {
  float getTemperatureInCelsius();
  float getVisibilityInKilometers();
}
  对于com.extension.weatherExtension接口的实现方法将自动在相应的XMLBeans实现类LocalWeatherDocumentXmlBeanImpl中生成。这些实现方法将委托给特定的扩展处理程序的com.extension.weatherExtensionHandler方法。
  扩展处理程序类com.extension.weatherExtensionHandler必须包括一个与接口方法有相同名称的public static方法,但是第一个参数必须为XmlObject类型,接下来是接口方法的参数,如下:

public static float getTemperatureInCelsius
(XmlObject xo) {

.....
}

public static float getVisibilityInKilometers
(XmlObject xo) {

.....
}
   每次LocalWeatherDocumentXmlBean实例的扩展方法被调用时,都将调用以上两个方法。
  因为XMLBeans根据模式生成文档类,所以这些文档类必须在其他任何依靠它们的扩展类编译前进行构建。由于这种循环的依赖性,建构所有部分需要一点技巧。
通过接口扩展功能构建XMLBeans分为三步。
将对extension元素的XML注释置于localInfo.xsdconfig文件中。然后,在从示例存档提取文件的工作目录的提示处,输入下列行:

scomp -out localinfo_XmlBeans.jar localInfo.xsd localInfo.xsdconfi使用localinfo_XmlBeans.jar和xbean.jar编译扩展接口和处理程序类。

SET CLASSPATH=%CLASSPATH%;localinfo_XmlBeans.jar;.;c:/xmlbeans-1.0.3/lib/xbean.jar
       javac -d . weatherExtension.java
       javac -d . weatherExtensionHandler.java删除localInfo.xsdconfig文件中围绕extension元素的XML注释。然后通过localInfo.xsd文件和localInfo.xsdconfig文件再次运行scomp,确保已编译的扩展类在classpath上。

scomp -out localinfo_XmlBeans.jar localInfo.xsd localInfo.xsdconfig  哇!我们已经准备好了编译并运行包含在示例存档中的基于XMLBeans的客户端应用程序extensionClient.java。


javac extensionClient.java
java extensionClient localInfo_68154.xml
  通过使用接口扩展功能,我们已经将附加逻辑从客户端应用程序移至XMLBean Java代码上。现在的代码已集中化并可重用。同时,XMLBean的客户端应用程序变得更简洁精练。

PrePost扩展
  使用prepost扩展功能时,在指定的XMLBeans的所有setter方法开始和结束时将生成对扩展处理程序的pre和post调用。
  我们说我们不希望我们的基于XMLBeans的客户端应用程序对由image元素的内容代表的映射进行修改。为了实行该约束,将下列extension元素添加到localInfo.xsdconfig文件中:

<xb:extension for="
com.weather.LocalWeatherDocumentXmlBean
">
 <xb:prePostSet>
  <xb:staticHandler>
    com.extension.MapPrePostSetHandler
  </xb:staticHandler>
 </xb:prePostSet>
</xb:extension>
  extension元素的for属性指定了按空间划分的XMLBeans的列表,其中setter方法按照下面LocalWeatherDocumentXmlBean类所展示的那样调用preSet()方法和postSet()方法:

/**
 * Sets the "image" element
 */
public void setMapXmlBean
        (com.weather.ImageTypeXmlBean mapXmlBean)
{
 synchronized (monitor())
 {
  check_orphaned();
  if ( com.extension.MapPrePostSetHandler.preSet
            (1, this, MAPXMLBEAN, false, -1)
      )
      {

       .... Code to set ImageTypeXmlBean instance
      }
  com.extension.MapPrePostSetHandler.postSet
              (1, this, MAPXMLBEAN, false, -1);
 }
}

/**
 * Appends and returns a new empty "image" element
 */
public com.weather.ImageTypeXmlBean
       addNewMapXmlBean()
{
 synchronized (monitor())
 {
  check_orphaned();
  com.weather.ImageTypeXmlBean target = null;
  if ( com.extension.MapPrePostSetHandler.preSet
            (2, this, MAPXMLBEAN, false, -1)
      )
      {
       ...
       Code to create and return an empty instance
       of ImageTypeXmlBean
       ...
      }
  com.extension.MapPrePostSetHandler.postSet
       (2, this, MAPXMLBEAN, false, -1);
  return target;
 }
}
  以上代码是使用PrePost扩展将生成什么结果的一个示例。注意在set方法和append方法中都调用了pre和post方法。
  以下是一些来自MapPrePostSetHandler.java的代码,说明了怎样实现阻止客户端应用程序修改image元素内容的preSet()和postSet()方法。

 public static boolean preSet (int operationType,
                XmlObject xo, QName propertyName,
                boolean isAttr, int indexOfItem){

  javax.xml.namespace.QName imageQName =
  new javax.xml.namespace.QName
  ("http://www.helloWeather.com/weather","image");

  if( (xo instanceof LocalWeather)
      && ( propertyName.equals(imageQName) ) )
   {
     return false;
   }

   return true;
 }
  ...

  public static void postSet(int operationType,
              XmlObject xo, QName propertyName,
              boolean isAttr, int indexOfItem)
   {}
  preSet()方法通知扩展处理器将对XMLBeans对象执行一些设置、插入或删除操作。这是扩展处理程序类必须阻止那个操作的最后机会。

  preSet()方法返回一个boolean值。如果返回的值是:
true,则执行要执行的操作。
false,则跳过要执行的操作。
  如果XMLBeans对象是LocalWeather的一个实例,并且要修改的属性是属于http://www.helloWeather.com/weather名称空间的image元素,我们的MapPrePostSetHandler的preSet()方法将返回false;否则,返回true。XMLBeans并不提供指定生成的XMLBeans类是否应当具有add、remove或set方法的功能。如前所述,我们能够在运行期间通过PrePost扩展功能来控制这些方法的流。
  操作完成或跳过操作之后,XMLBeans类调用postSet()方法。preSet()方法和postSet()方法的参数如下所示:


int operationType
Type of the operation. Possible values are org.apache.xmlbeans.impl.config.PrePostExtension.OPERATION_SET for set operations, org.apache.xmlbeans.impl.config.PrePostExtension.OPERATION_INSERT for add operations, and org.apache.xmlbeans.impl.config.PrePostExtension.OPERATION_REMOVE for remove operations.

XmlObject xo
Instance of XmlObject on which the operation is called.

QName propertyName
Qualified name of the element or attribute to be operated on.

boolean isAttr
true if the property is an attribute, otherwise false.

int indexOfItem
Index of the item to be set, when an element identified by propertyName allows several values, that is, declares maxOccurs > 1.

  构建既有interface扩展功能又有PrePost扩展功能的XMLBeans需要一点技巧,在示例存档的build.txt文件中对这些技巧进行了说明。存档文件中提供了说明PrePost扩展功能有效性的、基于XMLBeans的客户端应用程序prePostClient.java,存档文件可从以下“附加阅读”一节下载得到。

结束语
  XMLBeans的配置功能带来了许多益处,如减少代码维护成本的同时增加代码的灵活性。尽管prefix/suffix扩展在这些功能中作用或许最小,包命名功能却至关重要。接口扩展功能是把附加功能引入XMLBeans框架的好方法,同时PrePost扩展提供了一个穷人的AOP功能:对允许您执行的操作(比如根据某些条件有选择地执行一些操作)进行了包装。

附加阅读
· sample.zip——本文的示例模式、Java代码及XML文件。
· XMLBeans——Apache XMLBeans分发。
· 使用XMLBeans的XML-Java数据绑定——对XMLBeans的介绍。

你可能感兴趣的:(XmlBeans的使用)