时间:2005-03-10 作者:Hetal Shah 浏览次数: 4533 本文关键字:配置,XMLBeans |
|
本文通过一系列的示例对这些功能进行了说明。我们假设您已熟悉XMLBeans。对于入门者,参见下面列出的介绍XMLBeans的文章。本文中提及的示例代码和其他文件可以下载。示例已在Apache XMLBeans 1.0.3、Java 1.4.2_02和Microsoft Windows 2000上通过测试。
运行XMLBeans编译器时,可以指定可选配置文件来修正XMLBeans生成器的行为。默认情况下,该配置文件应当具有.xsdconfig扩展名。配置文件的结构遵循以下模式:
<?xml version="1.0" encoding="UTF-8"?> <xb:config xmlns:xb="http://xml.apache.org/xmlbeans/2004/02/xbean/config"> ... </xb:config>正如您所看到的,根config元素必须位于http://xml.apache.org/xmlbeans/2004/02/xbean/config名称空间中。真正的配置功能必须位于config元素之内,可按任何次序排放。
有了模式文件(比如someSchema.xsd)和配置文件(比如someConfig.xsdconfig)之后,下一步即是生成一系列代表该模式的XMLBeans类。以下为命令行用法示例:
scomp -out output_XmlBeans.jar someSchema.xsd someConfig.xsdconfig注意配置文件只是简单添加到scomp的附加参数。这将确保生成器使用您所指定的任何扩展功能。以下部分对这些功能依次进行了检查。
向已生成的类名添加前缀或后缀
XMLBeans提供了简单配置功能,用于从特定的名称空间中为模式类型创建的XMLBeans类名添加前缀名及后缀名。该功能对于将从特定名称空间中生成的模式类型的XMLBeans类同其他XMLBeans和在工程中使用的JavaBeans区别开来很有用。
这只是最简单的功能。我们在介绍模式示例时将还会使用这一部分。清单1显示了贯穿本文使用的localInfo.xsd模式。它描述了包含一个地点(基于邮编)天气信息的XML文档。
清单1. localInfo.xsd
<
xsd:schema
targetNamespace ="http://www.localInfo.com/LI"
...
xmlns:ns1 ="http://www.helloWeather.com/weather"
>
< xsd:import
namespace ="http://www.helloWeather.com/weather"
schemaLocation ="weather.xsd" />
< xsd:element name ="localInfo" >
< xsd:complexType >
< xsd:sequence >
< xsd:element ref ="ns1:localWeather" />
</ xsd:sequence >
< xsd:attribute ref ="Zipcode" />
</ xsd:complexType >
</ xsd:element >
< xsd:attribute name ="Zipcode" type ="xsd:string" />
</ xsd:schema >
targetNamespace ="http://www.localInfo.com/LI"
...
xmlns:ns1 ="http://www.helloWeather.com/weather"
>
< xsd:import
namespace ="http://www.helloWeather.com/weather"
schemaLocation ="weather.xsd" />
< xsd:element name ="localInfo" >
< xsd:complexType >
< xsd:sequence >
< xsd:element ref ="ns1:localWeather" />
</ xsd:sequence >
< xsd:attribute ref ="Zipcode" />
</ xsd:complexType >
</ xsd:element >
< xsd:attribute name ="Zipcode" type ="xsd:string" />
</ xsd:schema >
清单 2. weather.xsd
<
xsd:schema
targetNamespace
=
"http://www.helloWeather.com/weather"
....
>
< xsd:element name ="localWeather" >
< xsd:complexType >
< xsd:sequence >
< xsd:element ref ="Temperature" />
< xsd:element ref ="Humidity" />
< xsd:element ref ="Visibility" />
< xsd:element ref ="Datetime" />
< xsd:element ref ="image"
minOccurs ="1" maxOccurs ="1" />
</ xsd:sequence >
< xsd:attribute ref ="Zipcode" />
</ xsd:complexType >
</ xsd:element >
< xsd:element name ="Temperature"
type ="xsd:float" />
< xsd:element name ="Humidity"
type ="xsd:float" />
< xsd:element name ="Visibility"
type ="xsd:float" />
< xsd:element name ="Datetime"
type ="xsd:dateTime" />
< xsd:element name ="image"
type ="imageType" />
< xsd:attribute name ="Zipcode"
type ="xsd:string" />
< xsd:complexType name ="imageType" >
< xsd:simpleContent >
< xsd:extension base ="xsd:base64Binary" >
< xsd:attribute name ="type" use ="optional"
type ="xsd:string" />
</ xsd:extension >
</ xsd:simpleContent >
</ xsd:complexType >
"http://www.helloWeather.com/weather"
....
>
< xsd:element name ="localWeather" >
< xsd:complexType >
< xsd:sequence >
< xsd:element ref ="Temperature" />
< xsd:element ref ="Humidity" />
< xsd:element ref ="Visibility" />
< xsd:element ref ="Datetime" />
< xsd:element ref ="image"
minOccurs ="1" maxOccurs ="1" />
</ xsd:sequence >
< xsd:attribute ref ="Zipcode" />
</ xsd:complexType >
</ xsd:element >
< xsd:element name ="Temperature"
type ="xsd:float" />
< xsd:element name ="Humidity"
type ="xsd:float" />
< xsd:element name ="Visibility"
type ="xsd:float" />
< xsd:element name ="Datetime"
type ="xsd:dateTime" />
< xsd:element name ="image"
type ="imageType" />
< xsd:attribute name ="Zipcode"
type ="xsd:string" />
< xsd:complexType name ="imageType" >
< xsd:simpleContent >
< xsd:extension base ="xsd:base64Binary" >
< xsd:attribute name ="type" use ="optional"
type ="xsd:string" />
</ xsd:extension >
</ xsd:simpleContent >
</ xsd:complexType >
清单3:localInfo.xsdconfig:前缀和后缀的配置
<
xb:config
xmlns:xb
=
"http://xml.apache.org/xmlbeans/2004/02/xbean/config"
>
< xb:namespace uri ="##any" >
< xb:suffix > XmlBean </ xb:suffix >
< xb:prefix > pre </ xb:prefix >
</ xb:namespace >
</ xb:config >
"http://xml.apache.org/xmlbeans/2004/02/xbean/config"
>
< xb:namespace uri ="##any" >
< xb:suffix > XmlBean </ xb:suffix >
< xb:prefix > pre </ xb:prefix >
</ xb:namespace >
</ xb:config >
下一步是创建一个代表localInfo.xsd的一组XMLBeans类。在从示例存档提取文件的工作目录中提示处,输入下列行:
scomp-outlocalinfo_XmlBeans
.
jarlocalInfo
.
xsdlocalInfo
.
xsdconfig
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 >
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 >
从该示例可以看出,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 >
< xb:package > com.localInfo </ xb:package >
</ xb:namespace >
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$LocalWeather"
>
< xb:interface
name ="com.extension.weatherExtension" >
< xb:staticHandler >
com.extension.weatherExtensionHandler
</ xb:staticHandler >
</ xb:interface >
</ xb:extension >
"com.weather.LocalWeatherDocumentXmlBean$LocalWeather"
>
< xb:interface
name ="com.extension.weatherExtension" >
< xb:staticHandler >
com.extension.weatherExtensionHandler
</ xb:staticHandler >
</ xb:interface >
</ xb:extension >
public
interface
weatherExtension
...
{
floatgetTemperatureInCelsius();
floatgetVisibilityInKilometers();
}
floatgetTemperatureInCelsius();
floatgetVisibilityInKilometers();
}
扩展处理程序类com.extension.weatherExtensionHandler必须包括一个与接口方法有相同名称的public static方法,但是第一个参数必须为XmlObject类型,接下来是接口方法的参数,如下:
public
static
float
getTemperatureInCelsius
(XmlObjectxo) ... {
.....
}
public static float getVisibilityInKilometers
(XmlObjectxo) ... {
.....
}
(XmlObjectxo) ... {
.....
}
public static float getVisibilityInKilometers
(XmlObjectxo) ... {
.....
}
因为XMLBeans根据模式生成文档类,所以这些文档类必须在其他任何依靠它们的扩展类编译前进行构建。由于这种循环的依赖性,建构所有部分需要一点技巧。
通过接口扩展功能构建XMLBeans分为三步。
- 将对extension元素的XML注释置于localInfo.xsdconfig文件中。然后,在从示例存档提取文件的工作目录的提示处,输入下列行:
scomp-outlocalinfo_XmlBeans . jarlocalInfo . xsdlocalInfo . xsdconfig - 使用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 -
scomp-outlocalinfo_XmlBeans . jarlocalInfo . xsdlocalInfo . xsdconfig
哇!我们已经准备好了编译并运行包含在示例存档中的基于XMLBeans的客户端应用程序extensionClient.java。
javacextensionClient
.
java
javaextensionClientlocalInfo_68154 . xml
javaextensionClientlocalInfo_68154 . xml
PrePost扩展
使用prepost扩展功能时,在指定的XMLBeans的所有setter方法开始和结束时将生成对扩展处理程序的pre和post调用。
我们说我们不希望我们的基于XMLBeans的客户端应用程序对由image元素的内容代表的映射进行修改。为了实行该约束,将下列extension元素添加到localInfo.xsdconfig文件中:
<
xb:extension
for
="
com.weather.LocalWeatherDocumentXmlBean$LocalWeather
" >
< xb:prePostSet >
< xb:staticHandler >
com.extension.MapPrePostSetHandler
</ xb:staticHandler >
</ xb:prePostSet >
</ xb:extension >
com.weather.LocalWeatherDocumentXmlBean$LocalWeather
" >
< xb:prePostSet >
< xb:staticHandler >
com.extension.MapPrePostSetHandler
</ xb:staticHandler >
</ xb:prePostSet >
</ xb:extension >
/***/
/**
*Setsthe"image"element
*/
public void setMapXmlBean
(com.weather.ImageTypeXmlBeanmapXmlBean)
... {
synchronized(monitor())
...{
check_orphaned();
if(com.extension.MapPrePostSetHandler.preSet
(1,this,MAPXMLBEAN$8,false,-1)
)
...{
....CodetosetImageTypeXmlBeaninstance
}
com.extension.MapPrePostSetHandler.postSet
(1,this,MAPXMLBEAN$8,false,-1);
}
}
/***/ /**
*Appendsandreturnsanewempty"image"element
*/
public com.weather.ImageTypeXmlBean
addNewMapXmlBean()
... {
synchronized(monitor())
...{
check_orphaned();
com.weather.ImageTypeXmlBeantarget=null;
if(com.extension.MapPrePostSetHandler.preSet
(2,this,MAPXMLBEAN$8,false,-1)
)
...{
...
Codetocreateandreturnanemptyinstance
ofImageTypeXmlBean
...
}
com.extension.MapPrePostSetHandler.postSet
(2,this,MAPXMLBEAN$8,false,-1);
returntarget;
}
}
*Setsthe"image"element
*/
public void setMapXmlBean
(com.weather.ImageTypeXmlBeanmapXmlBean)
... {
synchronized(monitor())
...{
check_orphaned();
if(com.extension.MapPrePostSetHandler.preSet
(1,this,MAPXMLBEAN$8,false,-1)
)
...{
....CodetosetImageTypeXmlBeaninstance
}
com.extension.MapPrePostSetHandler.postSet
(1,this,MAPXMLBEAN$8,false,-1);
}
}
/***/ /**
*Appendsandreturnsanewempty"image"element
*/
public com.weather.ImageTypeXmlBean
addNewMapXmlBean()
... {
synchronized(monitor())
...{
check_orphaned();
com.weather.ImageTypeXmlBeantarget=null;
if(com.extension.MapPrePostSetHandler.preSet
(2,this,MAPXMLBEAN$8,false,-1)
)
...{
...
Codetocreateandreturnanemptyinstance
ofImageTypeXmlBean
...
}
com.extension.MapPrePostSetHandler.postSet
(2,this,MAPXMLBEAN$8,false,-1);
returntarget;
}
}
以下是一些来自MapPrePostSetHandler.java的代码,说明了怎样实现阻止客户端应用程序修改image元素内容的preSet()和postSet()方法。
public
static
boolean
preSet(
int
operationType,
XmlObjectxo,QNamepropertyName,
boolean isAttr, int indexOfItem) ... {
javax.xml.namespace.QNameimageQName=
newjavax.xml.namespace.QName
("http://www.helloWeather.com/weather","image");
if((xoinstanceofLocalWeather)
&&(propertyName.equals(imageQName)))
XmlObjectxo,QNamepropertyName,
boolean isAttr, int indexOfItem) ... {
javax.xml.namespace.QNameimageQName=
newjavax.xml.namespace.QName
("http://www.helloWeather.com/weather","image");
if((xoinstanceofLocalWeather)
&&(propertyName.equals(imageQName)))