jaxb
  1. jaxb
  2. JAXB-892

Marshaller creates an empty element if complexType is a simpleContent extending base type xs:string

    Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Minor Minor
    • Resolution: Unresolved
    • Affects Version/s: 2.2.5
    • Fix Version/s: None
    • Component/s: runtime
    • Labels:
      None

      Description

      I am not quite sure if this is a bug. It is not important though.

      Given the following schema:

      <xs:element name="foo">
      <xs:complexType>
      <xs:simpleContent>
      <xs:extension base="xs:string">
      ...
      </xs:extension>
      </xs:simpleContent>
      </xs:complexType>
      </xs:element>

      The generated class will look this way:

      public class Foo {
      @XmlValue
      protected String value;
      }

      Given the following XML:

      <foo/>

      The value-property of the Foo instance after unmarshalling is set to an empty String.

      This causes the marshaller to create the following XML after marshalling Foo:

      <foo></foo>

        Activity

        Hide
        sleepymurph added a comment -

        I came across this issue too.

        foo.setValue(null) marshals to "<foo/>"
        foo.setValue("") marshals to "<foo></foo>"

        This seems intuitive. However on unmarsalling, both forms yield an empty string for the value.

        "<foo/>" yields foo.getValue()==""
        "<foo></foo>" yields foo.getValue()==""

        This means if you're using JAXB to write information out to XML and then read it back in, you will lose null value information. I was trying to write a schema for a script of SQL statements and parameters, where the parameters would have an index attribute and contain their values:

        <statement>
          <sql>UPDATE someTable SET nullableColumn=?, nonNullColumn=?</sql>
          <parameter index="1"/>            <!-- null -->
          <parameter index="2"></parameter> <!-- '' -->
        </statement>
        

        I could create an object tree where the first parameter is null and the second is an empty string and it would marsal to the above XML, but on unmarshalling, the object tree would have empty strings for both parameters, effectively changing the statement:

        
        -- before:
        UPDATE someTable SET nullableColumn=NULL, nonNullColumn=''
        
        -- after:
        UPDATE someTable SET nullableColumn='', nonNullColumn=''
        

        This asymmetry between marshal and unmarshal makes this use case impossible. However, a quick glance at the xml spec seems to suggest that, officially, empty start+end tags and empty-element tags are equivalent.

        The representation of an empty element is either a start-tag immediately followed by an end-tag, or an empty-element tag.

        Maybe it's unwise for us to be wanting a consistent distinction in the first place?

        Show
        sleepymurph added a comment - I came across this issue too. foo.setValue(null) marshals to "<foo/>" foo.setValue("") marshals to "<foo></foo>" This seems intuitive. However on unmarsalling, both forms yield an empty string for the value. "<foo/>" yields foo.getValue()=="" "<foo></foo>" yields foo.getValue()=="" This means if you're using JAXB to write information out to XML and then read it back in, you will lose null value information. I was trying to write a schema for a script of SQL statements and parameters, where the parameters would have an index attribute and contain their values: <statement> <sql> UPDATE someTable SET nullableColumn=?, nonNullColumn=? </sql> <parameter index= "1" /> <!-- null --> <parameter index= "2" > </parameter> <!-- '' --> </statement> I could create an object tree where the first parameter is null and the second is an empty string and it would marsal to the above XML, but on unmarshalling, the object tree would have empty strings for both parameters, effectively changing the statement: -- before: UPDATE someTable SET nullableColumn=NULL, nonNullColumn='' -- after: UPDATE someTable SET nullableColumn='', nonNullColumn='' This asymmetry between marshal and unmarshal makes this use case impossible. However, a quick glance at the xml spec seems to suggest that, officially, empty start+end tags and empty-element tags are equivalent. The representation of an empty element is either a start-tag immediately followed by an end-tag, or an empty-element tag. Maybe it's unwise for us to be wanting a consistent distinction in the first place?
        Hide
        Iaroslav Savytskyi added a comment -

        Hi,

        As simple workaround you can mark that element as nillable. In this case after unmarshalling you will have null for null value, and "" for the empty string.

        Show
        Iaroslav Savytskyi added a comment - Hi, As simple workaround you can mark that element as nillable. In this case after unmarshalling you will have null for null value, and "" for the empty string.

          People

          • Assignee:
            Martin Grebac
            Reporter:
            mk0
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated: