GeoTools
  1. GeoTools
  2. GEOT-3350

Allow empty string element value for simple numeric types in XSISimpleTypes to avoid NumberFormatException

    Details

    • Type: Improvement Improvement
    • Status: Closed Closed
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: 2.7-M4
    • Fix Version/s: None
    • Component/s: xml
    • Labels:
      None
    • Environment:
      all

      Description

      Consider the following situation documents:

      doc1.xml:

      <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="schema.xsd">
        <value>3.14159</value>
      </root>
      

      doc2.xml:

      <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="schema.xsd">
        <value></value>
      </root>
      

      doc3.xml:

      <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="schema.xsd">
        <value xsi:nil="true"></value>
      </root>
      

      schema.xsd:

      <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
        <xs:element name="root">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="value" type="xs:double" minOccurs="0" nillable="true"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:schema>
      

      Obviously, doc2.xml is invalid, as an empty string is not a valid double. doc1.xml and doc3.xml are valid.

      In practice, I come across XML like doc2.xml in a gml:featureMember attribute element from an ArcGIS WFS service (except the element is not nillable according to DescribeFeatureType). When parsing the GML from a GetFeature request, the following exception occurs:

      java.io.IOException: org.xml.sax.SAXException: empty String
      	at org.geotools.xml.gml.FCBuffer.hasNext(FCBuffer.java:326)
      	at org.geotools.data.wfs.v1_0_0.WFSFeatureReader.loadElement(WFSFeatureReader.java:189)
      	at org.geotools.data.wfs.v1_0_0.WFSFeatureReader.hasNext(WFSFeatureReader.java:178)
      	at org.geotools.data.wfs.v1_0_0.NonStrictWFSStrategy.createFeatureReaderGET(NonStrictWFSStrategy.java:134)
      	at org.geotools.data.wfs.v1_0_0.NonStrictWFSStrategy.createFeatureReader(NonStrictWFSStrategy.java:101)
      	at org.geotools.data.wfs.v1_0_0.StrictWFSStrategy.access$101(StrictWFSStrategy.java:60)
      	at org.geotools.data.wfs.v1_0_0.StrictWFSStrategy$StrictFeatureReader.nextReader(StrictWFSStrategy.java:222)
      	at org.geotools.data.wfs.v1_0_0.StrictWFSStrategy$StrictFeatureReader.init(StrictWFSStrategy.java:171)
      	at org.geotools.data.wfs.v1_0_0.StrictWFSStrategy$StrictFeatureReader.<init>(StrictWFSStrategy.java:145)
      	at org.geotools.data.wfs.v1_0_0.StrictWFSStrategy.createFeatureReader(StrictWFSStrategy.java:84)
      	at org.geotools.data.wfs.v1_0_0.NonStrictWFSStrategy.getFeatureReader(NonStrictWFSStrategy.java:72)
      	at org.geotools.data.wfs.v1_0_0.WFS_1_0_0_DataStore.getFeatureReader(WFS_1_0_0_DataStore.java:747)
      Caused by: org.xml.sax.SAXException: empty String
      	at org.geotools.data.wfs.v1_0_0.WFSFeatureReader.run(WFSFeatureReader.java:140)
      

      The root exception location is actually not immediately apparent but here it is:

      java.lang.NumberFormatException: empty String
              at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:994)
              at java.lang.Double.valueOf(Double.java:475)
              at java.lang.Double.<init>(Double.java:567)
              at org.geotools.xml.xsi.XSISimpleTypes$Double.getValue(XSISimpleTypes.java:1123)
              at org.geotools.xml.handlers.SimpleElementHandler.endElement(SimpleElementHandler.java:123)
      

      As fixing the WFS to produce valid XML is not feasible, I would like to propose a patch to GeoTools to treat this as a null value instead.

      This could either be changing org.geotools.xml.handlers.SimpleElementHandler.endElement() to set "text" to null if text is an empty string and the type is numeric (maybe dates as well), or change the getValue() methods for each of the relevant inner classes (Integer, Double, Decimal, etc.) in org.geotools.xml.xsi.XSISimpleTypes from

                  if ((value.length == 1) && (value[0].getValue() != null)) {
                      return new java.lang.Double((java.lang.String) value[0]
                          .getValue());
                  }
      

      to

                  if ((value.length == 1) && (value[0].getValue() != null) && (!"".equals(value[0])) {
                      return new java.lang.Double((java.lang.String) value[0]
                          .getValue());
                  }
      

      or

                  if ((value.length == 1) && (value[0].getValue() != null)) {
                      try {
                          return new java.lang.Double((java.lang.String) value[0]
                              .getValue());
                      } catch(NumberFormatException nfe) {
                          return null;
                      }
                  }
      

      Changing SimpleElementHandler would however affect all SimpleTypes, it would not be correct to change an empty string for a xs:string element to null of course.

        Activity

        Hide
        Matthijs Laan added a comment -
        "Changing SimpleElementHandler would however affect all SimpleTypes, it would not be correct to change an empty string for a xs:string element to null of course."

        I meant here "Changing SimpleElementHandler to convert a empty "text" to null for any and all types would not be correct..." therefore it would need to be type dependent (numeric, maybe dates). So the changes in XSISimpleTypes inner classes would make more sense.
        Show
        Matthijs Laan added a comment - "Changing SimpleElementHandler would however affect all SimpleTypes, it would not be correct to change an empty string for a xs:string element to null of course." I meant here "Changing SimpleElementHandler to convert a empty "text" to null for any and all types would not be correct..." therefore it would need to be type dependent (numeric, maybe dates). So the changes in XSISimpleTypes inner classes would make more sense.
        Hide
        Matthijs Laan added a comment -
        Patch for Integer, Decimal, NegativeInteger, NonNegativeInteger, PositiveInteger, NonPositiveInteger, Long, Int, Short, Byte, UnsignedLong, UnsignedShort, UnsignedInt, UnsignedByte, Float, Double
        Show
        Matthijs Laan added a comment - Patch for Integer, Decimal, NegativeInteger, NonNegativeInteger, PositiveInteger, NonPositiveInteger, Long, Int, Short, Byte, UnsignedLong, UnsignedShort, UnsignedInt, UnsignedByte, Float, Double
        Hide
        Andrea Aime added a comment -
        XML is normally in Justin's area, though this is not the module Justin maintains actively. I'm going to be watcher as well, though not sure how helpful I can be
        Show
        Andrea Aime added a comment - XML is normally in Justin's area, though this is not the module Justin maintains actively. I'm going to be watcher as well, though not sure how helpful I can be
        Hide
        Justin Deoliveira added a comment -
        Patch looks good to me. +1.
        Show
        Justin Deoliveira added a comment - Patch looks good to me. +1.
        Hide
        Roy Braam added a comment -
        Patch applied in r36791
        Show
        Roy Braam added a comment - Patch applied in r36791
        Hide
        Andrea Aime added a comment -
        Mass closing all issues that have been in "resolved" state for more than one month without further comments
        Show
        Andrea Aime added a comment - Mass closing all issues that have been in "resolved" state for more than one month without further comments

          People

          • Assignee:
            Justin Deoliveira
            Reporter:
            Matthijs Laan
          • Votes:
            2 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: