JiBX
  1. JiBX
  2. JIBX-114

Unmarshalling and Marshalling of xml document creates different xml structures

    Details

    • Type: Bug Bug
    • Status: Closed Closed
    • Priority: Major Major
    • Resolution: Cannot Reproduce
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: core
    • Labels:
      None
    • Environment:
      Mac OSX 10.4 Using JDK 1.5
    • Number of attachments :
      0

      Description

      I am getting different XML document when marshalling and unmarshalling the same class data, using only default generated codes and no custom codes. The unmarshalling is the one causing the problem.

      Here's my binding file. The problem occurs in the instructions collection located in the first "x" element mapping.
      ===================================================
      <binding>
      <namespace uri="jabber:x:data" default="elements"/>

      <mapping name="x" ns="jabber:x:data"
      class="com.echomine.jabber.packet.DataXPacket" ordered='false'>
      <value name='type' field='formType' style='attribute'/>
      <collection field="instructions" type="java.util.ArrayList"
      item-type="java.lang.String" usage="optional">
      <value name='instructions' style='element' usage='optional'/>
      </collection>
      <value name='title' field='title' usage='optional'/>
      <collection field="fields" type="java.util.ArrayList"
      item-type="com.echomine.jabber.packet.DataXField" usage="optional"/>
      <collection field='itemFields' type='java.util.ArrayList'
      item-type='com.echomine.jabber.packet.DataXItemList' usage='optional'/>
      </mapping>

      <mapping name='item' ns='jabber:x:data' class='com.echomine.jabber.packet.DataXItemList'>
      <collection field="fields" type="java.util.ArrayList"
      item-type="com.echomine.jabber.packet.DataXField"/>
      </mapping>

      <mapping name='field' ns='jabber:x:data' ordered='false'
      class='com.echomine.jabber.packet.DataXField' >
      <value name='label' field='label' style='attribute' usage='optional'/>
      <value name='type' field='fieldType' style='attribute' usage='optional'/>
      <value name='var' field='variableName' style='attribute' usage='optional'/>
      <value name='desc' field='description' usage='optional'/>
      <value name='required' field='required' usage='optional'/>
      <collection field='options' type='java.util.ArrayList' usage='optional'
      item-type='com.echomine.jabber.packet.DataXOption'/>
      <collection field='values' type='java.util.ArrayList' usage='optional'
      item-type='java.lang.String'>
      <structure name='value' usage='optional'>
      <value style='text' usage='optional'/>
      </structure>
      </collection>
      </mapping>

      <mapping name='option' ns='jabber:x:data' class='com.echomine.jabber.packet.DataXOption'>
      <value name='label' field='label' style='attribute' usage='optional'/>
      <value name='value' field='value'/>
      </mapping>
      </binding>
      ===================================================
      Here's my testcase, with comments attached to the code:

      //this is the string that the marshalled document is compared to
      String xml = "<x xmlns='jabber:x:data' type='submit'><instructions>simple instructions</instructions></x>";
      StringReader reader = new StringReader(xml);
      DataXPacket packet = new DataXPacket();
      packet.addInstruction("simple instructions");
      //marshalls the object
      JiBXUtil.marshallObject(writer, packet);
      //the comparison passes with no problem, indicating that marshalling is bug-free
      compare(reader);
      reader.reset();
      // unmarshalls the reader string above
      packet = (DataXPacket) JiBXUtil.unmarshallObject(reader, DataXPacket.class);
      // this assertion below FAILS with the exception shown below
      assertEquals("simple instructions", packet.getInstructions());

      Here's the exception that I get when running the code:

      [junit] expected:<simple instructions> but was:<[simple instructions]>
      [junit] junit.framework.AssertionFailedError: expected:<simple instructions> but was:<[simple instructions]>
      [junit] at com.echomine.jabber.packet.DataXPacketTest.testInstructions(DataXPacketTest.java:133)

      It's interesting that the marshalling code is outputting expected xml, but the unmarshalling does not parse the data as expected.

      Is there a better way to write the binding file to parse the following type of schema?

      <xs:schema
      xmlns:xs='http://www.w3.org/2001/XMLSchema'
      targetNamespace='jabber:x:data'
      xmlns='jabber:x:data'
      elementFormDefault='qualified'>

      <xs:annotation>
      <xs:documentation>
      The protocol documented by this schema is defined in
      JEP-0004: http://www.jabber.org/jeps/jep-0004.html
      </xs:documentation>
      </xs:annotation>

      <xs:element name='x'>
      <xs:complexType>
      <xs:sequence>
      <xs:element name='instructions'
      minOccurs='0'
      maxOccurs='unbounded'
      type='xs:string'/>
      <xs:element name='title' minOccurs='0' type='xs:string'/>
      <xs:element ref='field' minOccurs='0' maxOccurs='unbounded'/>
      <xs:element ref='reported' minOccurs='0' maxOccurs='1'/>
      <xs:element ref='item' minOccurs='0' maxOccurs='unbounded'/>
      </xs:sequence>
      <xs:attribute name='type' use='required'>
      <xs:simpleType>
      <xs:restriction base='xs:NCName'>
      <xs:enumeration value='cancel'/>
      <xs:enumeration value='form'/>
      <xs:enumeration value='result'/>
      <xs:enumeration value='submit'/>
      </xs:restriction>
      </xs:simpleType>
      </xs:attribute>
      </xs:complexType>
      </xs:element>

      <xs:element name='field'>
      <xs:complexType>
      <xs:sequence>
      <xs:element name='desc' minOccurs='0' type='xs:string'/>
      <xs:element name='required' minOccurs='0' type='empty'/>
      <xs:element ref='value' minOccurs='0' maxOccurs='unbounded'/>
      <xs:element ref='option' minOccurs='0' maxOccurs='unbounded'/>
      </xs:sequence>
      <xs:attribute name='label' type='xs:string' use='optional'/>
      <xs:attribute name='type' use='optional' default='text-single'>
      <xs:simpleType>
      <xs:restriction base='xs:NCName'>
      <xs:enumeration value='boolean'/>
      <xs:enumeration value='fixed'/>
      <xs:enumeration value='hidden'/>
      <xs:enumeration value='jid-multi'/>
      <xs:enumeration value='jid-single'/>
      <xs:enumeration value='list-multi'/>
      <xs:enumeration value='list-single'/>
      <xs:enumeration value='text-multi'/>
      <xs:enumeration value='text-private'/>
      <xs:enumeration value='text-single'/>
      </xs:restriction>
      </xs:simpleType>
      </xs:attribute>
      <xs:attribute name='var' type='xs:string' use='optional'/>
      </xs:complexType>
      </xs:element>

      <xs:element name='option'>
      <xs:complexType>
      <xs:sequence>
      <xs:element ref='value'/>
      </xs:sequence>
      <xs:attribute name='label' type='xs:string' use='optional'/>
      </xs:complexType>
      </xs:element>

      <xs:element name='value' type='xs:string'/>

      <xs:element name='reported'>
      <xs:complexType>
      <xs:sequence>
      <xs:element ref='field' maxOccurs='unbounded'/>
      </xs:sequence>
      </xs:complexType>
      <xs:annotation>
      <xs:documentation>
      When contained in a "reported" element, the "field" element
      SHOULD NOT contain a "value" child.
      </xs:documentation>
      </xs:annotation>
      </xs:element>

      <xs:element name='item'>
      <xs:complexType>
      <xs:sequence>
      <xs:element ref='field' maxOccurs='unbounded'/>
      </xs:sequence>
      </xs:complexType>
      </xs:element>

      <xs:simpleType name='empty'>
      <xs:restriction base='xs:string'>
      <xs:enumeration value=''/>
      </xs:restriction>
      </xs:simpleType>

      </xs:schema>

        Activity

        Hide
        Chris Chen added a comment -

        I apologize, but this is not a bug. It is a bug in my testing code. I was testing the string against an array (which used to be a string) that contains a list of strings.

        I have fixed this and the test case is now running successfully.

        Show
        Chris Chen added a comment - I apologize, but this is not a bug. It is a bug in my testing code. I was testing the string against an array (which used to be a string) that contains a list of strings. I have fixed this and the test case is now running successfully.
        Hide
        Dennis Sosnoski added a comment -

        No worries. Glad you discovered the problem, Chris!

        Show
        Dennis Sosnoski added a comment - No worries. Glad you discovered the problem, Chris!

          People

          • Assignee:
            Unassigned
            Reporter:
            Chris Chen
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: