摘要
将遗留应用程序或集成系统与bea weblogic workshop集成在一起时,经常要用到xml和模式。然而,某些遗留系统在最初设计时并没有包括处理xml命名空间的功能。相反,这些遗留系统只接受不带目标命名空间的无格式xml消息,而这可能导致在weblogic workshop中出现冲突。事实上,可以在多个模式中定义名称相同的全局类型或元素。
本文描述了如何通过weblogic workshop和xmlbeans简单而有效地解决这个问题。本文假定您对xml模式和xmlbeans有一些基本了解。您可以下载本文中使用的示例。
简介
xmlbeans提供了一种处理xml的方法,即操作代表xml的java类。这些类是使用xml适合的模式来创建的。可以使用xmlbeans来编译一个或多个模式文件,从而生成java类型。
集成遗留解决方案时遇到的一个常见问题是,要与不同来源的多个模式打交道,而这些模式均未带有指定的目标命名空间。如果这些模式共享元素名称,weblogic workshop模式项目就无法成功编译生成的java类型,而且还会出现诸如“duplicate global type”或“duplicate global element”这样的错误。下面举例说明这样一个场景。
场景实例
假设您使用weblogic workshop创建了一个新的应用程序。通常您会创建一个模式项目,导入您的模式,然后weblogic workshop将自动把这个模式编译为xmlbeans:
<xs:schema xmlns:po="http://openuri.org/easypo" xmlns:xs="http://www.w3.org/2001/xmlschema" elementformdefault="qualified"> <xs:element name="purchase-order" type="customer"/> <xs:complextype name="customer"> <xs:sequence> <xs:element name="name" type="xs:string"/> <xs:element name="address" type="xs:string"/> </xs:sequence> </xs:complextype></xs:schema>
清单 1: schema1.xsd
schema1没有目标命名空间,所得到的xml文档中带有元素名称name和address,如下所示:
<?xml version="1.0" encoding="utf-8"?><purchase-order xmlns:po="http://openuri.org/easypo" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" > <name>john</name> <address>123 north first st</address></purchase-order>
清单 2: sample1.xml
如果您尝试从这个模式生成java类型,它将被正确地编译为一个xmlbean。现在可以导入另一个模式:
<xs:schema xmlns:xs="http://www.w3.org/2001/xmlschema" xmlns:foo="http://openuri.org/clientdb" elementformdefault="qualified"> <xs:element name="client-record" type="customer"/> <xs:complextype name="customer"> <xs:sequence> <xs:element name="name" type="xs:string"/> <xs:element name="address" type="xs:string"/> <xs:element name="phone" type="xs:string"/> </xs:sequence> </xs:complextype> <xs:element name="purchase-order" type="customer"/></xs:schema>
清单 3: schema2.xsd
schema2 同样没有目标命名空间。下面的xml文档就是这个模式的一个实例,它带有元素名称name, address和 phone:
<?xml version="1.0" encoding="utf-8"?><client-record xmlns:foo="http://openuri.org/clientdb" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"> <name>susan</name> <address>6789 south second st</address> <phone>408-123-4567</phone></client-record>
清单 4: sample2.xml
在weblogic workshop中,当把这两个模式文件导入到一个模式项目中并生成xmlbeans类时,weblogic workshop将显示编译错误:
error: error: duplicate global type: customererror: error: duplicate global element: purchase-order
可以看到,编译器提示说全局类型customer和全局元素purchase-order被多次定义。如果看看我们的模式,就会发现这并不值得惊奇。当模式不带目标命名空间时,这类冲突就很可能会出现。下面将给出解决这个问题的办法。
解决方案
有很多可行的解决方案都可以解决这个问题,我将挑出其中三种进行讨论。
解决方案1:添加目标命名空间
为模式添加不同的目标命名空间就可以解决这个问题――我们也推荐使用这种方法。但是,在大部分时间里您都无法控制模式,所以我们需要另寻出路。
解决方案2:创建单独的模式项目
解决该问题的另一种方法是在weblogic workshop中创建两个模式项目。在这个例子中,假设您在应用程序中创建了另一个schema项目,并分别在模式项目1和模式项目2中编译schema1.xsd和schema2.xsd,如图1所示。
在这种情况下,可以成功编译模式。两个项目都不会抱怨定义重复。然而,看看图1中生成的类便知,libraries文件夹包含两个jar文件,schemap1.jar和schemap2.jar,这两个文件是weblogic workshop编译的结果。两个jars文件中均定义了nonamespace.customer和nonamespace.purchaseorderdocument类,如下图所示:

图1: 一个包含两个模式项目的weblogic workshop应用程序
应用程序中创建了名称相同的java类(xmlbeans),结果您无法选择要在应用程序中使用的那一个。在这种情况下,还是存在前面出现过的冲突问题,但是这次遇到麻烦的是应用程序类加载器。
您还会注意到,java包名称“nonamespace”并非开发人员友好的,应该根据您的编码习惯对其进行修改。这也为实际的解决方案指明了方向――只要修改包名称便可避免冲突。第三种解决方案中可以解决这些问题。
解决方案3:使用xmlbeans配置文件
在dev2dev站点上,您可以读一篇有关xmlbeans编译器选项的优秀文章,即hetal shah编写的配置 xmlbeans(中文)(dev2dev,2004年11月)。这篇文章中提到,运行xmlbeans编译器时,您可以指定一个可选的配置文件,用于修改xmlbeans生成器的行为。这样就可以解决名称冲突和包名称不友好的问题。
您可以在模式“project1”中创建一个compiler1.xsdconfig文件,如图2所示。您将看到一个错误:
error: compiler1.xsdconfig:0: document d:/sp5/user_projects/domains/dev2dev/schemap1/compiler1.xsdconfig is not an xsd config file
您可以忽略上面的错误,不会出现问题,因为所创建的文件目前是空的和无效的。您可以使用这个配置文件指定java包的名称,从而为定义中缺少目标命名空间的xml元素和类型生成xmlbeans。此处的技巧在于使用保留字“##local”,如下所示:
<xb:config xmlns:xb="http://www.bea.com/2002/09/xbean/config"> <xb:namespace uri="##local"> <xb:package>com.foo>/xb:package> </xb:namespace></xb:config>
清单 5: compiler1.xsdconfig
现在,如果打开libraries文件夹,您将会看到模式“project1”jar包含java包com.foo中的类,而不是图1中nonamespace中的类。显然,您应该使用有效的java包名称,否则将产生错误。

图 2: weblogic workshop项目中xsdconfig.xml和结果jars文件的位置
现在,通过创建一个类似的compiler2.xsdconfig文件,您可以对project2执行同样的步骤。
结束语
遗留xml应用程序有时会省略命名空间,而这可能会导致集成问题。本文说明了如何使用xmlbeans配置文件编译模式,从而减轻这个问题带来的困扰。通过这个xmlbeans配置文件,您可以控制如何为生成的类型选择名称。设计该配置文件的目的是把模式类型名称映射为生成的java类型名称。当一些模式拥有相同的命名空间时,同样的方法可以防止类似问题的出现。
闽公网安备 35060202000074号