Hi Wing Yew,

Thanks for your response. I agree it is only a problem when using 1.5
runtime, and that xmlbeans using toPlainString() is not possible if it
is to support JDK 1.4.
Yes, the issue you mention is essentially the same thing, but the
workaround cited there doesn't always work. 

java.lang.System.out.println(new
java.math.BigDecimal("0.00000001").toString());
java.lang.System.out.println(new java.math.BigDecimal(new
java.math.BigDecimal("1E-8").toPlainString()).toString());

Prints out:

1E-8
1E-8

I guess I'll continue to use my PlainBigDecmial class below.

Many thanks,
Ian

-----Original Message-----
From: Wing Yew Poon [mailto:[EMAIL PROTECTED] 
Sent: 06 June 2006 19:38
To: [email protected]
Subject: RE: Problem with XMLBeans using Java 1.5 when creating
documents with small numbers

Ok, I reproduced the problem.
It would appear that the problem does not depend on whether XMLBeans is
built using 1.4 or 1.5; it depends on the runtime used when you run the
test program. 
I suppose the problem might be solved if XMLBeans used
BigDecimal#toPlainString()
instead of BigDecimal#toString(), but toPlainString() was added to
BigDecimal in JDK 1.5 and is not available in 1.4, and XMLBeans supports
JDK 1.4.
I think http://issues.apache.org/jira/browse/XMLBEANS-175 is essentially
the same issue that you raise.
- Wing Yew

-----Original Message-----
From: Wing Yew Poon
Sent: Tuesday, June 06, 2006 10:30 AM
To: [email protected]
Subject: RE: Problem with XMLBeans using Java 1.5 when creating
documents with small numbers

Ian,
what version of XMLBeans are you using?
do you build XMLBeans yourself (with JDK 1.5)? or do you use a binary
distribution?
- Wing Yew

-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
Sent: Tuesday, June 06, 2006 7:44 AM
To: [email protected]
Subject: Problem with XMLBeans using Java 1.5 when creating documents
with small numbers

Hi,
 
I have found a minor incompatibility with XMLBeans and Java 1.5 when
creating documents with small numbers. XMLBeans uses BigDecimal for
xs:decimal elements. The problems is essentially that
BigDecimal.toString() now returns exponents (e.g. 1.1E-8) in certain
circumstances, particularly with small numbers. The 'E' character is not
valid in xs:decimal, so you end up with an invalid xml document. 
 
I use BigDecimal.setScale to ensure that my BigDecimal variables don't
exceed the precision limits set by my schema. I first noticed this
problem when setting the scale on a zero BigDecimal - new
BigDecimal(0).setScale(9).toString(), yields "0E-9". The below example
shows the problem using a test schema:

<?xml version="1.0" encoding="UTF-8" ?> <xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"; xmlns="test"
targetNamespace="test">
        <xs:element name="test" type="Test"/>
        <xs:complexType name="Test">
                <xs:annotation/>
                <xs:sequence>
                        <xs:element name="test" type="TestNo"
minOccurs="0" maxOccurs="unbounded"/>
                </xs:sequence>
        </xs:complexType>
        <xs:simpleType name="TestNo">
                <xs:restriction base="xs:decimal">
                        <xs:fractionDigits value="9" /> 
                        <xs:totalDigits value="18" /> 
                </xs:restriction>
        </xs:simpleType>
</xs:schema>

My test program is:
________________________________________________________________________
__
public static void main(String[] args)
{
    TestDocument doc = TestDocument.Factory.newInstance();
    Test test = doc.addNewTest();
    test.addTest(new BigDecimal(1.2345678923456789).setScale(9
,BigDecimal.ROUND_HALF_UP)));
    test.addTest(new BigDecimal(0.0000000111).setScale(9
,BigDecimal.ROUND_HALF_UP)));
    test.addTest(new BigDecimal(0).setScale(9
,BigDecimal.ROUND_HALF_UP)));
    test.addTest(new BigDecimal(0.000001));
    test.addTest(new BigDecimal(0));
    
    ArrayList validationErrors = new ArrayList();
    XmlOptions validationOptions = (new
XmlOptions()).setErrorListener(validationErrors);
    if (!doc.validate(validationOptions)) {
        Iterator iter = validationErrors.iterator();
        while (iter.hasNext()) {
            System.out.println(iter.next());
        }
    }
    System.out.println(doc.toString());
}
________________________________________________________________________
__

This prints out:
________________________________________________________________________
__
error: decimal: Invalid decimal value: unexpected char '69'
error: decimal: Invalid decimal value: unexpected char '69'
error: decimal: Invalid decimal value: unexpected char '69'
<test xmlns="test">
  <test xmlns="">1.234567892</test>
  <test xmlns="">1.1E-8</test>
  <test xmlns="">0E-9</test>
  <test
xmlns="">9.999999999999999547481118258862586856139387236908078193664E-7<
/test>
  <test xmlns="">0</test>
</test>
 
________________________________________________________________________
__

The long term solution, I guess, is to use BigDecimal.toPlainString()
when creating an xml document within the xml beans code
(JavaDecimalHolder.compute_text). However, this would make xmlbeans
incompatible with Java 1.4 which I'm sure is not possible. 

In the short term (i.e. with current xmlBeans), as far as I can see
there are two ways around this. 
1.      Use XMLBeans' generated types to force the string value.
However, this rather bloats code as each 'set' becomes 3 lines. For
example:

interest.setAmt(bigDecimal.setScale(3,BigDecimal.ROUND_HALF_UP));
becomes:
AmountOfMoney money = AmountOfMoney.Factory.newInstance();
money.setStringValue(bigDecimal.setScale(3,BigDecimal.ROUND_HALF_UP).toP
lainString());
interest.xsetAmt(money);

2.      Create a new class that inherits from BigDecimal who's toString
calls toPlainString, to restore the Java 1.4 behaviour, as below:

public class PlainBigDecimal extends BigDecimal {
    public PlainBigDecimal(BigDecimal bd)
    {
        super(bd.unscaledValue(),bd.scale());
    }
    
    public String toString()
    {
        return super.toPlainString();
    }
}

With this our example becomes:

...
test.addTest(new PlainBigDecimal(new
BigDecimal(0.0000000111).setScale(9,BigDecimal.ROUND_HALF_UP)));
test.addTest(new PlainBigDecimal(new
BigDecimal(0).setScale(9,BigDecimal.ROUND_HALF_UP)));
...

Which prints:

<test xmlns="test">
  <test xmlns="">0.000000011</test>
  <test xmlns="">0.000000000</test>
</test>

Please let me know if you can think of any better solutions.

Kind regards,
Ian Jones

Visit our website at http://www.ubs.com

This message contains confidential information and is intended only for
the individual named.  If you are not the named addressee you should not
disseminate, distribute or copy this e-mail.  Please notify the sender
immediately by e-mail if you have received this e-mail by mistake and
delete this e-mail from your system.

E-mail transmission cannot be guaranteed to be secure or error-free as
information could be intercepted, corrupted, lost, destroyed, arrive
late or incomplete, or contain viruses.  The sender therefore does not
accept liability for any errors or omissions in the contents of this
message which arise as a result of e-mail transmission.  If verification
is required please request a hard-copy version.  This message is
provided for informational purposes and should not be construed as a
solicitation or offer to buy or sell any securities or related financial
instruments.


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

_______________________________________________________________________
Notice:  This email message, together with any attachments, may contain
information  of  BEA Systems,  Inc.,  its subsidiaries  and  affiliated
entities,  that may be confidential,  proprietary,  copyrighted  and/or
legally privileged, and is intended solely for the use of the individual
or entity named in this message. If you are not the intended recipient,
and have received this message in error, please immediately return this
by email and then delete it.

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

_______________________________________________________________________
Notice:  This email message, together with any attachments, may contain
information  of  BEA Systems,  Inc.,  its subsidiaries  and  affiliated
entities,  that may be confidential,  proprietary,  copyrighted  and/or
legally privileged, and is intended solely for the use of the individual
or entity named in this message. If you are not the intended recipient,
and have received this message in error, please immediately return this
by email and then delete it.

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


Visit our website at http://www.ubs.com

This message contains confidential information and is intended only
for the individual named.  If you are not the named addressee you
should not disseminate, distribute or copy this e-mail.  Please
notify the sender immediately by e-mail if you have received this
e-mail by mistake and delete this e-mail from your system.

E-mail transmission cannot be guaranteed to be secure or error-free
as information could be intercepted, corrupted, lost, destroyed,
arrive late or incomplete, or contain viruses.  The sender therefore
does not accept liability for any errors or omissions in the contents
of this message which arise as a result of e-mail transmission.  If
verification is required please request a hard-copy version.  This
message is provided for informational purposes and should not be
construed as a solicitation or offer to buy or sell any securities or
related financial instruments.


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to