Further to my earlier post about MappingTool, it seems that the tool has problems with handling choices.
 
For a schema like:
<complexType name="a">
    <sequence>
        <choice>
            <element name="b" type="string"></element>
            <element name="c" type="string"></element>
        </choice>
    </sequence>
</complexType>
 
Then the mapping generated by MappingTool from the generated DTOs has cst:required="true" attributes for both elements/fields.  This seems incorrect to me, since both fields are not required: what is required is that exactly one of the fields be provided.
 
 
Regards
Dean
 
 
 
-----Original Message-----
From: Chalker, Dean [mailto:[EMAIL PROTECTED]
Sent: Wednesday, 16 July 2003 4:23 PM
To: [EMAIL PROTECTED]
Subject: [castor-dev] Mapping generated Castor classes

Hi Keith et al.
 
I've just spent some time playing with mapping with the Unmarshaller, and I have a couple of observations/questions.
 
With 0.9.5 and org.exolab.castor.builder.javaclassmapping=type and a split schema in two namespaces:
 
split-namespace-1.xsd::
<?xml version="1.0" encoding="UTF-8"?>
<schema targetNamespace="http://www.xyz.com/test"
            xmlns="http://www.w3.org/2001/XMLSchema"
            xmlns:test="http://www.xyz.com/test"
            xmlns:test2="http://www.xyz.com/test2"
            elementFormDefault="qualified">
    <import namespace="http://www.xyz.com/test2" schemaLocation="split-namespace-2.xsd"/>
    <complexType name="e">
        <sequence>
            <element name="stringField" type="string"/>
            <element name="intField" type="int"/>
            <element name="f" type="test2:f"/>
        </sequence>
    </complexType>
</schema>
 
split-namespace-2.xsd::
<?xml version="1.0" encoding="UTF-8"?>
<schema targetNamespace="http://www.xyz.com/test2"
            xmlns="http://www.w3.org/2001/XMLSchema"
            xmlns:test="http://www.xyz.com/test2"
            elementFormDefault="qualified">
    <complexType name="f">
        <sequence>
            <element name="stringField" type="string"/>
            <element name="intField" type="int"/>
        </sequence>
    </complexType>
</schema>
 
 
Suppose I have the following an XML message:
<e xmlns=\"http://www.xyz.com/test\">
    <stringField>aString</stringField>
    <intField>1</intField>
    <f>
        <stringField>bString</stringField>
        <intField>2</intField>
    </f>
</e>
 
then unmarshalling with the following code works ok:
Reader reader = new StringReader(input1);
E e = (E)Unmarshaller.unmarshal(E.class, reader);
 
If I use MappingTool to generate a mapping, I get the following:
<?xml version="1.0" encoding="UTF-8"?>
<mapping xmlns="http://castor.exolab.org/" xmlns:cst="http://castor.exolab.org/">
    <description>Castor generated mapping file</description>
    <class cst:name="F">
        <description>Default mapping for class F</description>
        <map-to cst:xml="f" cst:ns-uri="http://www.xyz.com/test2"/>
        <field cst:name="stringField" cst:type="java.lang.String" cst:required="true">
            <bind-xml name="stringField" node="element"/>
        </field>
        <field cst:name="intField" cst:type="int" cst:required="true">
            <bind-xml name="intField" node="element"/>
        </field>
    </class>
    <class cst:name="E">
        <description>Default mapping for class E</description>
        <map-to cst:xml="e" cst:ns-uri="http://www.xyz.com/test"/>
        <field cst:name="stringField" cst:type="java.lang.String" cst:required="true">
            <bind-xml name="stringField" node="element"/>
        </field>
        <field cst:name="intField" cst:type="int" cst:required="true">
            <bind-xml name="intField" node="element"/>
        </field>
        <field cst:name="f" cst:type="F" cst:required="true">
            <bind-xml name="f" node="element"/>
        </field>
    </class>
</mapping>
 
If I try to use this generated mapping with the following unmarshalling code:
Reader reader = new StringReader(inputString);
InputSource source = new InputSource(new StringReader(mappingString));
Mapping mapping = new Mapping(getClass().getClassLoader());
mapping.loadMapping(source);
Unmarshaller unm = new Unmarshaller(mapping);
E e = (E)unm.unmarshal(reader);
I get the dreaded "unable to find FieldDescriptor for 'stringField' in ClassDescriptor of e" exception.
 
I believe that the error may be with MappingTool.  Looking at some of the examples, I see mappings like
<?xml version="1.0"?>
<mapping xmlns:xyz="http://www.acme.org/xyz">
   <class name="Root">
      <map-to xml="root" ns-prefix="xyz" ns-uri="http://www.acme.org/xyz"/>
      <field name="name" type="string">
            <bind-xml name="xyz:name" node="attribute"/>
      </field>
      <field name="child" type="Child">
            <bind-xml name="xyz:child" node="element"/>
      </field>
   </class>
 
   <class name="Child">
      <field name="content" type="string">
            <bind-xml node="text"/>
      </field>
   </class>
</mapping>
 
which include a ns-prefix for the target namespace.  If I change the generated mapping to include prefixes for the target namespaces, the unmarshalling works.
 
<mapping xmlns="http://castor.exolab.org/" xmlns:cst="http://castor.exolab.org/" xmlns:test="http://www.xyz.com/test" xmlns:test2="http://www.xyz.com/test2">
    <class cst:name="F">
    <map-to cst:xml="f" cst:ns-prefix="test2" cst:ns-uri="http://www.xyz.com/test2"/>
    <field cst:name="stringField" cst:type="java.lang.String" cst:required="true">
        <bind-xml name="test2:stringField" node="element"/>
    </field>
    ...
</mapping>
 
 
I am surprised that not more use is made of the descriptor class files when mapping generated classes.  In the current example, I had naively thought that it should be possible to just provide a skelton mapping, with the missing details being drawn from the descriptor classes.  Specifically, I had thought
    <class cst:name="E">
        <map-to cst:xml="e" cst:ns-prefix="test" cst:ns-uri="http://www.xyz.com/test"/>
    </class>
</mapping>
 
would be enough to make the current example work, since the field descriptors and child class descriptors could be sourced from the descriptor classes.  However, this appears not to be the case, and instead, I need to provide a complete mapping of all classes and fields.  I guess that this is the reason that the MappingTool exists.
 
I think I am suggesting that where generated classes are being mapped, that the mapping operate as an override for the descriptor classes, rather than as a parallel representation.  There are probably valid reasons why this is not the case.
 
Regards and thanks for past help
Dean
 

Reply via email to