castor
  1. castor
  2. CASTOR-2010

Namespace problem when using multiple namespaces

    Details

    • Type: Bug Bug
    • Status: Open Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 1.1
    • Fix Version/s: None
    • Component/s: XML
    • Labels:
      None
    • Environment:
      Java 1.4, Windows 2000
    • Number of attachments :
      0

      Description

      Hi all,

      I am not 100% sure if this is a bug or if there is a workaround but I have created this as a bug. I am trying to use Castor 1.0M4 as my binding framework inside of XFire 1.2.6 but I am running into a namespace problem. I can reproduce the problem using Castor 1.1 which is what I will describe now. I have a Castor mapping file that defines the mapping for a class "order.Order" in the "http://order" namespace. This order has an orderNumber and 2 names. The names are of type "common.Name" which is in the "http://common" namespace. The mapping file looks as follows:

      <?xml version="1.0" encoding="UTF-8"?>
      <mapping>
      <class name="order.Order">
      <map-to xml="order" ns-uri="http://order" ns-prefix="order"/>
      <field name="orderNumber" type="integer">
      <bind-xml name="order-number" node="element"/>
      </field>
      <field name="sellerName" type="common.Name">
      <bind-xml name="seller-name" node="element"/>
      </field>
      <field name="buyerName" type="common.Name">
      <bind-xml name="buyer-name" node="element"/>
      </field>
      </class>
      <class name="common.Name">
      <map-to xml="name" ns-uri="http://common" ns-prefix="common"/>
      <field name="firstName" type="java.lang.String">
      <bind-xml name="first-name" node="element"/>
      </field>
      <field name="lastName" type="java.lang.String">
      <bind-xml name="last-name" node="element"/>
      </field>
      </class>
      </mapping>

      When I create an instance of Order and pass in an orderNumber and 2 names, Castor generates the following XML:

      <?xml version="1.0" encoding="UTF-8"?>
      <order:order xmlns:order="http://order">
      <order:order-number>1234</order:order-number>
      <common:seller-name xmlns:common="http://common">
      <common:first-name>Bob</common:first-name>
      <common:last-name>Smith</common:last-name>
      </common:seller-name>
      <common:buyer-name xmlns:common="http://common">
      <common:first-name>Fred</common:first-name>
      <common:last-name>Peterson</common:last-name>
      </common:buyer-name>
      </order:order>

      The important thing to note in the XML generated above is that the "seller-name" and "buyer-name" namespaces are "common" and not "order". The problem is that I cannot generate an XML schema for this (I want a schema for my common types and another for the order). If my seller-name and buyer-name complex types use the "type" attribute to specify my common Name type, then the namespace of seller-name and buyer-name should be "order" and not "common". If my complex types use the "ref" attribute to point to a Name element in my common schema, then I cannot change the name of the element from "name" to "buyer-name" and "seller-name". Please let me know if I am missing something and there is a way to have Castor generate XML in such a way that I can break out the schemas.

      Here are the different schemas I have tried:

      Attempt 1:

      This is how I originally wanted to have my schemas. I have a common schema that defines my "name" type and my order schema uses that type using the "type" attribute:

      The common.xsd:

      <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:common="http://common" targetNamespace="http://common" elementFormDefault="qualified">
      <xsd:complexType name="name">
      <xsd:sequence>
      <xsd:element name="first-name" type="string"/>
      <xsd:element name="last-name" type="string"/>
      </xsd:sequence>
      </xsd:complexType>
      </xsd:schema>

      The order.xsd:

      <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://order" xmlns:order="http://order" xmlns:common="http://common" elementFormDefault="qualified">
      <xsd:import namespace="http://common" schemaLocation="common.xsd"/>
      <xsd:element name="order">
      <xsd:complexType>
      <xsd:sequence>
      <xsd:element name="order-number" type="xsd:integer"/>
      <xsd:element name="buyer-name" type="common:name"/>
      <xsd:element name="seller-name" type="common:name"/>
      </xsd:sequence>
      </xsd:complexType>
      </xsd:element>
      </xsd:schema>

      The problem with these schemas is that namespace expected for the "seller-name" and "buyer-name" is "order" and not "common". So either I need to be able to configure Castor to return the different namespace (remember, Castor is returning the "common" namespace for the name elements) or I can't use these schemas. Here is an XML that is validated by these schemas:

      <?xml version="1.0" encoding="UTF-8"?>
      <order:order xmlns:order="http://order" xmlns:common="http://common">
      <order:order-number>1234</order:order-number>
      <order:seller-name>
      <common:first-name>Bob</common:first-name>
      <common:last-name>Smith</common:last-name>
      </order:seller-name>
      <order:buyer-name>
      <common:first-name>Fred</common:first-name>
      <common:last-name>Peterson</common:last-name>
      </order:buyer-name>
      </order:order>

      Attempt 2:

      In order to get the correct namespace for the name elements in the schema, I could define an element in my common schema and refer to this element in the order schema using the "ref" attribute as follows:

      The common.xsd (note: I am defining an element instead of a type now):

      <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:common="http://common" targetNamespace="http://common" elementFormDefault="qualified">
      <xsd:element name="name">
      <xsd:complexType>
      <xsd:sequence>
      <xsd:element name="first-name" type="string"/>
      <xsd:element name="last-name" type="string"/>
      </xsd:sequence>
      </xsd:complexType>
      </xsd:element>
      </xsd:schema>

      The order.xsd (note: I am using the "ref" attribute in the element instead of specifying a name):

      <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://order" xmlns:order="http://order" xmlns:common="http://common" elementFormDefault="qualified">
      <xsd:import namespace="http://common" schemaLocation="common.xsd"/>
      <xsd:element name="order">
      <xsd:complexType>
      <xsd:sequence>
      <xsd:element name="order-number" type="xsd:integer"/>
      <xsd:element ref="common:name"/>
      <xsd:element ref="common:name"/>
      </xsd:sequence>
      </xsd:complexType>
      </xsd:element>
      </xsd:schema>

      With these schemas the namespace for the "name" elements are "common" but now both of the "name" elements need to be called "name". I cannot use the "seller-name" or "buyer-name" names. Here is an XML that is validated by these schemas:

      <order:order xmlns:order="http://order" xmlns:common="http://common">
      <order:order-number>1234</order:order-number>
      <common:name>
      <common:first-name>Bob</common:first-name>
      <common:last-name>Smith</common:last-name>
      </common:name>
      <common:name>
      <common:first-name>Fred</common:first-name>
      <common:last-name>Peterson</common:last-name>
      </common:name>
      </order:order>

      Attempt 3:

      The only way I was able to create a schema that would validate the output generated by Castor was to nest my common elements inside a dummy element using the "location" attribute in the Castor mapping file as follows. I replaced my "buyerName" and "sellerName" mapping as follows:

      <field name="sellerName" type="common.Name">
      <bind-xml name="name" node="element" location="seller-name"/>
      </field>
      <field name="buyerName" type="common.Name">
      <bind-xml name="name" node="element" location="buyer-name"/>
      </field>

      This generates the following XML where I have the "seller-name" and "buyer-name" in the "order" schema that has a nested "name" element in the "common" schema:

      <?xml version="1.0" encoding="UTF-8"?>
      <order:order xmlns:order="http://order">
      <order:order-number>1234</order:order-number>
      <order:seller-name>
      <common:name xmlns:common="http://common">
      <common:first-name>Bob</common:first-name>
      <common:last-name>Smith</common:last-name>
      </common:name>
      </order:seller-name>
      <order:buyer-name>
      <common:name xmlns:common="http://common">
      <common:first-name>Fred</common:first-name>
      <common:last-name>Peterson</common:last-name>
      </common:name>
      </order:buyer-name>
      </order:order>

      Here is the common.xsd:

      <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:common="http://common" targetNamespace="http://common" elementFormDefault="qualified">
      <xsd:element name="name">
      <xsd:complexType>
      <xsd:sequence>
      <xsd:element name="first-name" type="string"/>
      <xsd:element name="last-name" type="string"/>
      </xsd:sequence>
      </xsd:complexType>
      </xsd:element>
      </xsd:schema>

      And this is the order.xsd:

      <?xml version="1.0" encoding="UTF-8"?>
      <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://order" xmlns:order="http://order" xmlns:common="http://common" elementFormDefault="qualified">
      <xsd:import namespace="http://common" schemaLocation="common.xsd"/>
      <xsd:element name="order">
      <xsd:complexType>
      <xsd:sequence>
      <xsd:element name="order-number" type="xsd:integer"/>
      <xsd:element name="seller-name">
      <complexType >
      <xsd:sequence>
      <xsd:element ref="common:name"/>
      </xsd:sequence>
      </complexType>
      </xsd:element>
      <xsd:element name="buyer-name">
      <complexType >
      <xsd:sequence>
      <xsd:element ref="common:name"/>
      </xsd:sequence>
      </complexType>
      </xsd:element>
      </xsd:sequence>
      </xsd:complexType>
      </xsd:element>
      </xsd:schema>

      As you can see this makes the schema a lot more complicated and I don't like the fact that I need to have both a "seller-name" and a "name" element nested. But that's the only way I found it to work.

      Thanks for your help,
      Josh

        Activity

        Werner Guttmann made changes -
        Field Original Value New Value
        Assignee Werner Guttmann [ wguttmn ]

          People

          • Assignee:
            Werner Guttmann
            Reporter:
            Josh
          • Votes:
            2 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated: