Handling Schemas without Namespaces in WebLogic Workshop 8.1by Bea Chan AbstractWhen integrating legacy applications or integration systems with BEA WebLogic Workshop you frequently rely on XML and schemas. However, some legacy systems were not originally designed to handle XML namespaces. Instead, these legacy systems only accept plain XML messages without target namespaces, and this can create conflicts in WebLogic Workshop. Indeed, global types or elements with the same name may be defined in multiple schemas. This article describes how WebLogic Workshop and XMLBeans can help address this problem in a powerful and elegant way. The article assumes you have basic knowledge of XML schemas and XMLBeans. You can download the examples used in this article. IntroductionXMLBeans provides a way to handle XML by manipulating Java classes that represent the XML. The classes are created using a schema to which the XML conforms. You can use XMLBeans to compile one or multiple schema files to generate Java types. A common problem encountered when integrating legacy solutions is working with multiple schemas from different sources, each without a specified target namespace. If these schemas share element names, WebLogic Workshop schema projects are unable to successfully compile the generated Java types, and errors such as "Duplicate global type" or "Duplicate global element" appear. A scenario is illustrated as below: ScenarioAssume you use WebLogic Workshop and you create a new application. Typically you create a schema project, import your schema, and WebLogic Workshop automatically compiles it into 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>
Listing 1: Schema1.xsd Schema1, with no target namespace, gives the following XML document with element name <?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>
Listing 2: Sample1.xml If you try generating Java types from this schema you'll see that the schema is properly compiled into an XMLBean. Now you can import another schema: <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>
Listing 3: Schema2.xsd Schema2 doesn't have a target namespace either. The following XML document is an instance of this schema, with element name <?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>
Listing 4: Sample2.xml When these two schema files are imported into a schema project in WebLogic Workshop and XMLBeans classes are generated, WebLogic Workshop is going to display compilation errors: ERROR: error: Duplicate global type: customer ERROR: error: Duplicate global element: purchase-order As you can see the compiler complains that the global type SolutionsYou can choose from a number of possible solutions to this problem. I'll discuss three solutions here. S1: Add a target namespaceAdding different target namespaces to your schemas would solve the problem—and this is the recommended approach. Unfortunately, most of the time you have no control over the schemas and you need to find another way. S2: Create a separate schema projectAnother approach to solving the problem is to create two schema projects in WebLogic Workshop. In this example, assume you create another Schema project in your application and compile schema1.xsd and schema2.xsd respectively in schema project1 and schema project2, as shown in Figure 1. In this case the schemas will compile successfully. Each project will not complain about duplicate definitions. However, take a look at the generated classes shown in Figure 1. The
Java classes (XMLBeans) with the same name have been created in your application; as a result, you will not be able to select which one you want to use in your application. In this case, you have the same name collision problem as before, but this time it is with the application classloader. Observe also the Java package name "noNamespace" may not be developer-friendly and should be changed to adhere to your coding conventions. This points the way to a real solution—if you change the package name you'll avoid the conflict. These issues can be solved in the third approach. S3: Using an XMLBeans configuration fileYou can read an excellent article about XMLBeans compiler options on Dev2Dev. See Configuring XMLBeans by Hetal Shah (Dev2Dev, November 2004). As the article illustrates, when running the XMLBeans compiler you can specify an optional configuration file that modifies the behavior of the XMLBeans generator. In this case, name collisions and unfriendly package names can be addressed. You can create a ERROR: compiler1.xsdconfig:0: Document D:\SP5\user_projects\domains\Dev2Dev\SchemaP1\compiler1.xsdconfig is not an xsd config file You can safely ignore the above error, since the created file is empty and invalid for now. You are going to use the configuration file to specify the Java package name used to generate XMLBeans for XML elements and types defined with no target namespace. The trick is to use the reserve words <xb:config xmlns:xb="http://www.bea.com/2002/09/xbean/config">
<!-- Use the "namespace" element to map a namespace to
the Java package name that should be generated. -->
<xb:namespace uri="##local">
<xb:package>com.foo</xb:package>
</xb:namespace>
</xb:config>
Listing 5: compiler1.xsdconfig Now if you go to the
Now you can perform the same steps on Project2 by creating a similar SummaryLegacy XML applications sometimes omit namespaces, and this can cause an integration headache. This article shows how to relieve the pain by compiling your schema with an XMLBeans configuration file. This XMLBeans configuration file lets you control how names are chosen for the generated types. The configuration file is designed to map schema type names to generated Java type names. This same approach can prevent similar issues from arising when schemas have identical namespaces. DownloadDownload the sample schema, xsdconfig, and XML files for this article: schemaex.zip References
Bea Chan is a Senior Developer Relations Engineer with BEA. Beaky is a Sun Certified Java Programmer. Return to dev2dev. |
Tutorial Tools Related Products Check out the products mentioned in this article:Related Technologies Related Articles Bookmark Tutorial
|