Same element name but different complex type

View: New views
5 Messages — Rating Filter:   Alert me  

Same element name but different complex type

by John Gan :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Some parts of this message have been removed. Learn more about Nabble's security policy.

Hi,

 

I’m really new to xmlbeans and I have a question. I have 2 xsd files which have pretty much the same element names. The only difference is that they have some complex types which have different elements inside them but have same global element name, e.g.:

 

Books.xsd would have a complex type called ItemProperties:

 

                    <xs:element minOccurs="0" name="ItemProperties">

                      <xs:complexType>

                        <xs:sequence>

                          <xs:element minOccurs="0" name="ISBN" nillable="true" type="xs:string" />

                          <xs:element minOccurs="0" name="Author" nillable="true" type="xs:string" />

                          <xs:element minOccurs="0" name="of-Pages" nillable="true" type="xs:string" />

                          <xs:element minOccurs="0" name="Series-Vol." nillable="true" type="xs:string" />

                          <xs:element minOccurs="0" name="Publisher" nillable="true" type="xs:string" />

                        </xs:sequence>

                      </xs:complexType>

                    </xs:element>

 

Apparel.xsd would also have a complex type call ItemProperties:

 

                    <xs:element minOccurs="0" name="ItemProperties">

                      <xs:complexType>

                        <xs:sequence>

                          <xs:element minOccurs="0" name="Style" nillable="true" type="Style_Type" />

                          <xs:element minOccurs="0" name="Womens-Sizes" nillable="true" type="Womens-Sizes_Type" />

                          <xs:element minOccurs="0" name="Sizes" nillable="true" type="Sizes_Type" />

                          <xs:element minOccurs="0" name="Infant-Child-sizes" nillable="true" type="Infant-Child-sizes_Type" />

                          <xs:element minOccurs="0" name="Juniors-Sizes" nillable="true" type="Juniors-Sizes_Type" />

                        </xs:sequence>

                      </xs:complexType>

                    </xs:element>

 

They both have the same namespace and I can’t change them because that is given to me:

 

<?xml version="1.0" encoding="utf-8"?>

<xs:schema xmlns="http://www.mysite.com/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www. mysite.com/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema">

 

The wiki said to use multiple class loaders for each jar to solve this issue of same namespace and element names. So I compiled them into .jar with scomp individually since sfactor would give me an error and I think the error is because there are complex types with same name but different internal structure?

 

I found this sample code from the mailing list back in 2005:

 

        // get a SchemaTypeLoader from an array of directories or jar
files
 
        File[] schemaPath = null;
 
        SchemaTypeLoader stl =
XmlBeans.typeLoaderForResource(XmlBeans.resourceLoaderForPath(schemaPath
));
 
 
 
        // include the built-in type system
 
        stl = XmlBeans.typeLoaderUnion(new
SchemaTypeLoader[]{XmlBeans.getBuiltinTypeSystem(), stl});
 
 
 
        // parse the document in the given 
 
        a.b.c.RETURNDATADocument doc =
(a.b.c.RETURNDATADocument)stl.parse("xml", null, null);
 
 
 
        // or create a new one, given a schemaType
 
        SchemaType st = stl.findDocumentType(new QName("a.b.c",
"RETURNDATA"));
 
        a.b.c.RETURNDATADocument newDoc =
(a.b.c.RETURNDATADocument)stl.newInstance(st, null);

 

I tried to compile each xsd with the following xsdconfig file:

 

For books.xsd:

 

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

 

  <xb:namespace uri="http://www.mysite.com/XMLSchema">

    <xb:package>com.mysite.XMLSchema.Book</xb:package>

  </xb:namespace>

 

</xb:config>

 

For apparel.xsd:

 

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

 

  <xb:namespace uri="http://www.mysite.com/XMLSchema">

    <xb:package>com.mysite.XMLSchema.Apparel</xb:package>

  </xb:namespace>

 

</xb:config>

 

And this is my source code:

 

import java.io.File;

import javax.xml.namespace.QName;

import org.apache.xmlbeans.SchemaType;

import org.apache.xmlbeans.SchemaTypeLoader;

import org.apache.xmlbeans.XmlBeans;

import org.apache.xmlbeans.XmlException;

import com.mysite.XMLSchema.Apparel.ItemDataFeedDocument;

 

 

public class Test {

 

      /**

       * @param args

       * @throws XmlException

       */

      public static void main(String[] args) {

 

            File[] schemaPath = {new File("Apparel.jar"), new File("Books.jar")};

        SchemaTypeLoader stl = XmlBeans.typeLoaderForResource(XmlBeans.resourceLoaderForPath(schemaPath));

 

        stl = XmlBeans.typeLoaderUnion(new SchemaTypeLoader[]{XmlBeans.getBuiltinTypeSystem(), stl});       

       

        SchemaType st = stl.findDocumentType(new QName("com.mysite.XMLSchema.Apparel", "ItemDataFeed"));

 

        com.mysite.XMLSchema.Apparel.ItemDataFeedDocument newDoc1 = (com.mysite.XMLSchema.Apparel.ItemDataFeedDocument)stl.newInstance(st, null);

        com.mysite.XMLSchema.Accessories.ItemDataFeedDocument newDoc2 = (com.mysite.XMLSchema.Accessories.ItemDataFeedDocument)stl.newInstance(st, null);

       

        com.mysite.XMLSchema.Apparel.ItemDataFeedDocument.ItemDataFeed apparel = newDoc1.addNewItemDataFeed();

        com.mysite.XMLSchema.Apparel.ItemDataFeedDocument.ItemDataFeed.Items apparelItems = apparel.addNewItems();

        com.mysite.XMLSchema.Apparel.ItemDataFeedDocument.ItemDataFeed.Items.Item aItem = apparelItems.addNewItem();

        com.mysite.XMLSchema.Apparel.ItemDataFeedDocument.ItemDataFeed.Items.Item.ItemProperties itemProp = aItem.addNewItemProperties();

        itemProp.setAge(com.mysite.XMLSchema.Apparel.AgeType.TEEN);

       

        System.out.println(newDoc1.toString());

      }

}

 

 

But SchemaType st would just return null? What am I doing wrong and is there a better solution to the problem? I just want to be able to create new instances of the xmlbean classes that have the same namespace and element name (but different internal structures for the complex types). Then set some values for the elements and write to file.

 

Any help is greatly appreciated.

John


RE: Same element name but different complex type

by Radu Preotiuc-Pietro :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Some parts of this message have been removed. Learn more about Nabble's security policy.
John,
 
It's actually simpler than that. But first of all, let me ask you where on the wiki have you found the bit with using multiple typeloaders?
 
I am assuming that, since you have references to com.mysite.XMLSchema.Apparel.ItemDataFeedDocument in your code, your classpath contains both Apparel.jar and Books.jar. In this case just do
 
        SchemaTypeLoader stl = XmlBeans.getContextTypeLoader();
and you have a SchemaTypeLoader that has access to both types' definitions.
 
But here's the main trick: the findDocumentType() method expects the QName from the Schema as its argument (new QName("http://www.mysite.com/XMLSchema", "ItemDataFeed")) but because the target namespace is the same, this will not work (you will not be able to get both types, for Apparel and for Book, but only the one that is first on the classpath)! So instead, get the Schema type directly from its associated class:
 
        com.mysite.XMLSchema.Apparel.ItemDataFeedDocument newDoc1 = (com.mysite.XMLSchema.Apparel.ItemDataFeedDocument)stl.newInstance(com.mysite.XMLSchema.Apparel.ItemDataFeedDocument.type, null);
This will work and, by replacing "Apparel" with "Book" in the package names, you can create Book items too.
 
Hope this helps,
Radu


From: John Gan [mailto:john.gan@...]
Sent: Tuesday, April 22, 2008 7:33 PM
To: user@...
Subject: Same element name but different complex type

Hi,

 

I’m really new to xmlbeans and I have a question. I have 2 xsd files which have pretty much the same element names. The only difference is that they have some complex types which have different elements inside them but have same global element name, e.g.:

 

Books.xsd would have a complex type called ItemProperties:

 

                    <xs:element minOccurs="0" name="ItemProperties">

                      <xs:complexType>

                        <xs:sequence>

                          <xs:element minOccurs="0" name="ISBN" nillable="true" type="xs:string" />

                          <xs:element minOccurs="0" name="Author" nillable="true" type="xs:string" />

                          <xs:element minOccurs="0" name="of-Pages" nillable="true" type="xs:string" />

                          <xs:element minOccurs="0" name="Series-Vol." nillable="true" type="xs:string" />

                          <xs:element minOccurs="0" name="Publisher" nillable="true" type="xs:string" />

                        </xs:sequence>

                      </xs:complexType>

                    </xs:element>

 

Apparel.xsd would also have a complex type call ItemProperties:

 

                    <xs:element minOccurs="0" name="ItemProperties">

                      <xs:complexType>

                        <xs:sequence>

                          <xs:element minOccurs="0" name="Style" nillable="true" type="Style_Type" />

                          <xs:element minOccurs="0" name="Womens-Sizes" nillable="true" type="Womens-Sizes_Type" />

                          <xs:element minOccurs="0" name="Sizes" nillable="true" type="Sizes_Type" />

                          <xs:element minOccurs="0" name="Infant-Child-sizes" nillable="true" type="Infant-Child-sizes_Type" />

                          <xs:element minOccurs="0" name="Juniors-Sizes" nillable="true" type="Juniors-Sizes_Type" />

                        </xs:sequence>

                      </xs:complexType>

                    </xs:element>

 

They both have the same namespace and I can’t change them because that is given to me:

 

<?xml version="1.0" encoding="utf-8"?>

<xs:schema xmlns="http://www.mysite.com/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www. mysite.com/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema">

 

The wiki said to use multiple class loaders for each jar to solve this issue of same namespace and element names. So I compiled them into .jar with scomp individually since sfactor would give me an error and I think the error is because there are complex types with same name but different internal structure?

 

I found this sample code from the mailing list back in 2005:

 

        // get a SchemaTypeLoader from an array of directories or jar
files
 
        File[] schemaPath = null;
 
        SchemaTypeLoader stl =
XmlBeans.typeLoaderForResource(XmlBeans.resourceLoaderForPath(schemaPath
));
 
 
 
        // include the built-in type system
 
        stl = XmlBeans.typeLoaderUnion(new
SchemaTypeLoader[]{XmlBeans.getBuiltinTypeSystem(), stl});
 
 
 
        // parse the document in the given 
 
        a.b.c.RETURNDATADocument doc =
(a.b.c.RETURNDATADocument)stl.parse("xml", null, null);
 
 
 
        // or create a new one, given a schemaType
 
        SchemaType st = stl.findDocumentType(new QName("a.b.c",
"RETURNDATA"));
 
        a.b.c.RETURNDATADocument newDoc =
(a.b.c.RETURNDATADocument)stl.newInstance(st, null);

 

I tried to compile each xsd with the following xsdconfig file:

 

For books.xsd:

 

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

 

  <xb:namespace uri="http://www.mysite.com/XMLSchema">

    <xb:package>com.mysite.XMLSchema.Book</xb:package>

  </xb:namespace>

 

</xb:config>

 

For apparel.xsd:

 

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

 

  <xb:namespace uri="http://www.mysite.com/XMLSchema">

    <xb:package>com.mysite.XMLSchema.Apparel</xb:package>

  </xb:namespace>

 

</xb:config>

 

And this is my source code:

 

import java.io.File;

import javax.xml.namespace.QName;

import org.apache.xmlbeans.SchemaType;

import org.apache.xmlbeans.SchemaTypeLoader;

import org.apache.xmlbeans.XmlBeans;

import org.apache.xmlbeans.XmlException;

import com.mysite.XMLSchema.Apparel.ItemDataFeedDocument;

 

 

public class Test {

 

      /**

       * @param args

       * @throws XmlException

       */

      public static void main(String[] args) {

 

            File[] schemaPath = {new File("Apparel.jar"), new File("Books.jar")};

        SchemaTypeLoader stl = XmlBeans.typeLoaderForResource(XmlBeans.resourceLoaderForPath(schemaPath));

 

        stl = XmlBeans.typeLoaderUnion(new SchemaTypeLoader[]{XmlBeans.getBuiltinTypeSystem(), stl});       

       

        SchemaType st = stl.findDocumentType(new QName("com.mysite.XMLSchema.Apparel", "ItemDataFeed"));

 

        com.mysite.XMLSchema.Apparel.ItemDataFeedDocument newDoc1 = (com.mysite.XMLSchema.Apparel.ItemDataFeedDocument)stl.newInstance(st, null);

        com.mysite.XMLSchema.Accessories.ItemDataFeedDocument newDoc2 = (com.mysite.XMLSchema.Accessories.ItemDataFeedDocument)stl.newInstance(st, null);

       

        com.mysite.XMLSchema.Apparel.ItemDataFeedDocument.ItemDataFeed apparel = newDoc1.addNewItemDataFeed();

        com.mysite.XMLSchema.Apparel.ItemDataFeedDocument.ItemDataFeed.Items apparelItems = apparel.addNewItems();

        com.mysite.XMLSchema.Apparel.ItemDataFeedDocument.ItemDataFeed.Items.Item aItem = apparelItems.addNewItem();

        com.mysite.XMLSchema.Apparel.ItemDataFeedDocument.ItemDataFeed.Items.Item.ItemProperties itemProp = aItem.addNewItemProperties();

        itemProp.setAge(com.mysite.XMLSchema.Apparel.AgeType.TEEN);

       

        System.out.println(newDoc1.toString());

      }

}

 

 

But SchemaType st would just return null? What am I doing wrong and is there a better solution to the problem? I just want to be able to create new instances of the xmlbean classes that have the same namespace and element name (but different internal structures for the complex types). Then set some values for the elements and write to file.

 

Any help is greatly appreciated.

John


Notice: This email message, together with any attachments, may contain information of BEA Systems, Inc., its subsidiaries and affiliated entities, that may be confidential, proprietary, copyrighted and/or legally privileged, and is intended solely for the use of the individual or entity named in this message. If you are not the intended recipient, and have received this message in error, please immediately return this by email and then delete it.

RE: Same element name but different complex type

by John Gan :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Some parts of this message have been removed. Learn more about Nabble's security policy.

Hi Radu,

 

Thanks for the reply.  I have another question, I don’t suppose there is a way to dynamically load the schema at runtime from a user and still be able to probe and execute methods that are unique to the loaded schema? In other words, the schema is not known ahead of time nor has a jar file in the build path. Basically apply my situation of same namespace and element name to schemas that are not known ahead of time. Does Java’s “ClassLoader” (not XmlBean’s “SchemaTypeLoader”) have something to do with it? I’m still a Java rookie and don’t know much about ClassLoaders. I just wanted to be pointed in the correct direction if Java’s “ClassLoader” is the solution or XmlBean’s “SchemaTypeLoader” is the solution.

 

Here is the link to the wiki that says to use class loaders when changing the package names:

 

http://wiki.apache.org/xmlbeans/XmlBeansFaq#configPackageName

 

The last paragraph in this section says the following:

 

Note: XMLBeans doesn’t support using two or more sets of java classes (in different packages) mapped to schema types/elements that have the same names and target namespaces, using all in the same class loader. Depending on the direction you are using for the java classes to schema types mapping, some features might not work correctly. This is because even though the package names for the java classes are different, the schema location for the schema metadata (.xsb files) is the same and contains the corresponding implementing java class, so the JVM will always pick up the first on the classpath. This can be avoided if multiple class loaders are used.

 

Thanks again,

John

 


From: Radu Preotiuc-Pietro [mailto:radup@...]
Sent: Thursday, April 24, 2008 7:43 PM
To: user@...
Subject: RE: Same element name but different complex type

 

John,

 

It's actually simpler than that. But first of all, let me ask you where on the wiki have you found the bit with using multiple typeloaders?

 

I am assuming that, since you have references to com.mysite.XMLSchema.Apparel.ItemDataFeedDocument in your code, your classpath contains both Apparel.jar and Books.jar. In this case just do

 

        SchemaTypeLoader stl = XmlBeans.getContextTypeLoader();

and you have a SchemaTypeLoader that has access to both types' definitions.

 

But here's the main trick: the findDocumentType() method expects the QName from the Schema as its argument (new QName("http://www.mysite.com/XMLSchema", "ItemDataFeed")) but because the target namespace is the same, this will not work (you will not be able to get both types, for Apparel and for Book, but only the one that is first on the classpath)! So instead, get the Schema type directly from its associated class:

 

        com.mysite.XMLSchema.Apparel.ItemDataFeedDocument newDoc1 = (com.mysite.XMLSchema.Apparel.ItemDataFeedDocument)stl.newInstance(com.mysite.XMLSchema.Apparel.ItemDataFeedDocument.type, null);

This will work and, by replacing "Apparel" with "Book" in the package names, you can create Book items too.

 

Hope this helps,

Radu

 


From: John Gan [mailto:john.gan@...]
Sent: Tuesday, April 22, 2008 7:33 PM
To: user@...
Subject: Same element name but different complex type

Hi,

 

I’m really new to xmlbeans and I have a question. I have 2 xsd files which have pretty much the same element names. The only difference is that they have some complex types which have different elements inside them but have same global element name, e.g.:

 

Books.xsd would have a complex type called ItemProperties:

 

                    <xs:element minOccurs="0" name="ItemProperties">

                      <xs:complexType>

                        <xs:sequence>

                          <xs:element minOccurs="0" name="ISBN" nillable="true" type="xs:string" />

                          <xs:element minOccurs="0" name="Author" nillable="true" type="xs:string" />

                          <xs:element minOccurs="0" name="of-Pages" nillable="true" type="xs:string" />

                          <xs:element minOccurs="0" name="Series-Vol." nillable="true" type="xs:string" />

                          <xs:element minOccurs="0" name="Publisher" nillable="true" type="xs:string" />

                        </xs:sequence>

                      </xs:complexType>

                    </xs:element>

 

Apparel.xsd would also have a complex type call ItemProperties:

 

                    <xs:element minOccurs="0" name="ItemProperties">

                      <xs:complexType>

                        <xs:sequence>

                          <xs:element minOccurs="0" name="Style" nillable="true" type="Style_Type" />

                          <xs:element minOccurs="0" name="Womens-Sizes" nillable="true" type="Womens-Sizes_Type" />

                          <xs:element minOccurs="0" name="Sizes" nillable="true" type="Sizes_Type" />

                          <xs:element minOccurs="0" name="Infant-Child-sizes" nillable="