0

I need a lossless conversion of XML to JSON and back again using Java. I have used a Javascript library called jsonxml, which does it properly, but nothing in Java.

The best I seem to have found it JSON-java, which is mention often in Stack Overflow, but it fails testing on too many fronts.

Here are my test case code...

//---------------------------------------------------
import org.json.*;
//---------------------------------------------------
public class rjx
    {
    //-----------------------------------------------
    private String j2x(String json)
        {
        return(XML.toString(new JSONObject(json)));
        }
    //-----------------------------------------------
    private String x2j(String xml)
        {
        return(XML.toJSONObject(xml).toString());
        }
    //-----------------------------------------------
    //-----------------------------------------------
    public static void main(String[] args)
        {
        //-------------------------------------------
        rjx o = new rjx();
        //-------------------------------------------
        try
            {
            String xml = new String();
            String reversed = new String();
            System.out.println("=======");
            xml = "<e/>";
            System.out.println(xml);
            reversed = o.j2x(o.x2j(xml));
            System.out.println(reversed);
            if (xml.equals(reversed))
                System.out.println("PASS");
            else
                System.out.println("FAIL");
            System.out.println("-------");
            xml = "<e>text</e>";
            System.out.println(xml);
            reversed = o.j2x(o.x2j(xml));
            System.out.println(reversed);
            if (xml.equals(reversed))
                System.out.println("PASS");
            else
                System.out.println("FAIL");
            System.out.println("-------");
            xml = "<e name='value' />";
            System.out.println(xml);
            reversed = o.j2x(o.x2j(xml));
            System.out.println(reversed);
            if (xml.equals(reversed))
                System.out.println("PASS");
            else
                System.out.println("FAIL");
            System.out.println("-------");
            xml = "<e name='value'>text</e>";
            System.out.println(xml);
            reversed = o.j2x(o.x2j(xml));
            System.out.println(reversed);
            if (xml.equals(reversed))
                System.out.println("PASS");
            else
                System.out.println("FAIL");
            System.out.println("-------");
            xml = "<e><a>text</a><b>text</b></e>";
            System.out.println(xml);
            reversed = o.j2x(o.x2j(xml));
            System.out.println(reversed);
            if (xml.equals(reversed))
                System.out.println("PASS");
            else
                System.out.println("FAIL");
            System.out.println("-------");
            xml = "<e><a>text</a><a>text</a></e>";
            System.out.println(xml);
            reversed = o.j2x(o.x2j(xml));
            System.out.println(reversed);
            if (xml.equals(reversed))
                System.out.println("PASS");
            else
                System.out.println("FAIL");
            System.out.println("-------");
            xml = "<e>text<a>text</a></e>";
            System.out.println(xml);
            reversed = o.j2x(o.x2j(xml));
            System.out.println(reversed);
            if (xml.equals(reversed))
                System.out.println("PASS");
            else
                System.out.println("FAIL");
            System.out.println("-------");
            xml = "<a>hello</a>";
            System.out.println(xml);
            reversed = o.j2x(o.x2j(xml));
            System.out.println(reversed);
            if (xml.equals(reversed))
                System.out.println("PASS");
            else
                System.out.println("FAIL");
            System.out.println("-------");
            xml = "<a x='y'>hello</a>";
            System.out.println(xml);
            reversed = o.j2x(o.x2j(xml));
            System.out.println(reversed);
            if (xml.equals(reversed))
                System.out.println("PASS");
            else
                System.out.println("FAIL");
            System.out.println("-------");
            xml = "<a id='a'><b id='b'>hey!</b></a>";
            System.out.println(xml);
            reversed = o.j2x(o.x2j(xml));
            System.out.println(reversed);
            if (xml.equals(reversed))
                System.out.println("PASS");
            else
                System.out.println("FAIL");
            System.out.println("-------");
            xml = "<a>x<c/>y</a>";
            System.out.println(xml);
            reversed = o.j2x(o.x2j(xml));
            System.out.println(reversed);
            if (xml.equals(reversed))
                System.out.println("PASS");
            else
                System.out.println("FAIL");
            System.out.println("-------");
            xml = "<x u=''/>";
            System.out.println(xml);
            reversed = o.j2x(o.x2j(xml));
            System.out.println(reversed);
            if (xml.equals(reversed))
                System.out.println("PASS");
            else
                System.out.println("FAIL");
            System.out.println("-------");
            xml = "<html><head><title>Xml/Json</title><meta name='x' content='y' /></head><body></body></html>";
            System.out.println(xml);
            reversed = o.j2x(o.x2j(xml));
            System.out.println(reversed);
            if (xml.equals(reversed))
                System.out.println("PASS");
            else
                System.out.println("FAIL");
            System.out.println("-------");
            xml = "<ol class='xoxo'><li>Subject 1<ol><li>subpoint a</li><li>subpoint b</li></ol></li><li><span>Subject 2</span><ol compact='compact'><li>subpoint c</li><li>subpoint d</li></ol></li></ol>";
            System.out.println(xml);
            reversed = o.j2x(o.x2j(xml));
            System.out.println(reversed);
            if (xml.equals(reversed))
                System.out.println("PASS");
            else
                System.out.println("FAIL");
            System.out.println("-------");
            xml = "<span class='vevent'><a class='url' href='http://www.web2con.com/'><span class='summary'>Web 2.0 Conference</span><abbr class='dtstart' title='2005-10-05'>October 5</abbr><abbr class='dtend' title='2005-10-08'>7</abbr><span class='location'>Argent Hotel, San Francisco, CA</span></a></span>";
            System.out.println(xml);
            reversed = o.j2x(o.x2j(xml));
            System.out.println(reversed);
            if (xml.equals(reversed))
                System.out.println("PASS");
            else
                System.out.println("FAIL");
            System.out.println("-------");
            xml = "<e><![CDATA[ .. some data .. ]]></e>";
            System.out.println(xml);
            reversed = o.j2x(o.x2j(xml));
            System.out.println(reversed);
            if (xml.equals(reversed))
                System.out.println("PASS");
            else
                System.out.println("FAIL");
            System.out.println("-------");
            xml = "<e><a /><![CDATA[ .. some data .. ]]><b /></e>";
            System.out.println(xml);
            reversed = o.j2x(o.x2j(xml));
            System.out.println(reversed);
            if (xml.equals(reversed))
                System.out.println("PASS");
            else
                System.out.println("FAIL");
            System.out.println("-------");
            xml = "<e>some text<![CDATA[ .. some data .. ]]>more text</e>";
            System.out.println(xml);
            reversed = o.j2x(o.x2j(xml));
            System.out.println(reversed);
            if (xml.equals(reversed))
                System.out.println("PASS");
            else
                System.out.println("FAIL");
            System.out.println("-------");
            xml = "<e>some text<![CDATA[ .. some data .. ]]><a /></e>";
            System.out.println(xml);
            reversed = o.j2x(o.x2j(xml));
            System.out.println(reversed);
            if (xml.equals(reversed))
                System.out.println("PASS");
            else
                System.out.println("FAIL");
            System.out.println("-------");
            xml = "<e><![CDATA[ .. some data .. ]]><![CDATA[ .. more data .. ]]></e>";
            System.out.println(xml);
            reversed = o.j2x(o.x2j(xml));
            System.out.println(reversed);
            if (xml.equals(reversed))
                System.out.println("PASS");
            else
                System.out.println("FAIL");
            System.out.println("-------");
            xml = "<e><![CDATA[ .. some data .. ]]><![CDATA[ .. & more data .. ]]></e>";
            System.out.println(xml);
            reversed = o.j2x(o.x2j(xml));
            System.out.println(reversed);
            if (xml.equals(reversed))
                System.out.println("PASS");
            else
                System.out.println("FAIL");
            System.out.println("-------");
            xml = "<e><![CDATA[ .. some data .. ]]><![PCDATA[ .. &amp; still more data .. ]]></e>";
            System.out.println(xml);
            reversed = o.j2x(o.x2j(xml));
            System.out.println(reversed);
            if (xml.equals(reversed))
                System.out.println("PASS");
            else
                System.out.println("FAIL");
            System.out.println("=======");
            }
        catch (Exception e)
            {
            System.err.println("error: rjx.main>>" + e.toString());
            System.exit(1);
            }
        System.exit(0);
        }
    //-----------------------------------------------
    }
//---------------------------------------------------

And the results...

=======
<e/>
<e/>
PASS
-------
<e>text</e>
<e>text</e>
PASS
-------
<e name='value' />
<e><name>value</name></e>
FAIL
-------
<e name='value'>text</e>
<e><name>value</name>text</e>
FAIL
-------
<e><a>text</a><b>text</b></e>
<e><a>text</a><b>text</b></e>
PASS
-------
<e><a>text</a><a>text</a></e>
<e><a>text</a><a>text</a></e>
PASS
-------
<e>text<a>text</a></e>
<e><a>text</a>text</e>
FAIL
-------
<a>hello</a>
<a>hello</a>
PASS
-------
<a x='y'>hello</a>
<a><x>y</x>hello</a>
FAIL
-------
<a id='a'><b id='b'>hey!</b></a>
<a><b><id>b</id>hey!</b><id>a</id></a>
FAIL
-------
<a>x<c/>y</a>
<a><c/>x
y</a>
FAIL
-------
<x u=''/>
<x><u/></x>
FAIL
-------
<html><head><title>Xml/Json</title><meta name='x' content='y' /></head><body></body></html>
<html><head><meta><name>x</name>y</meta><title>Xml/Json</title></head><body/></html>
FAIL
-------
<ol class='xoxo'><li>Subject 1<ol><li>subpoint a</li><li>subpoint b</li></ol></li><li><span>Subject 2</span><ol compact='compact'><li>subpoint c</li><li>subpoint d</li></ol></li></ol>
<ol><class>xoxo</class><li><ol><li>subpoint a</li><li>subpoint b</li></ol>Subject 1</li><li><ol><compact>compact</compact><li>subpoint c</li><li>subpoint d</li></ol><span>Subject 2</span></li></ol>
FAIL
-------
<span class='vevent'><a class='url' href='http://www.web2con.com/'><span class='summary'>Web 2.0 Conference</span><abbr class='dtstart' title='2005-10-05'>October 5</abbr><abbr class='dtend' title='2005-10-08'>7</abbr><span class='location'>Argent Hotel, San Francisco, CA</span></a></span>
<span><a><href>http://www.web2con.com/</href><abbr><title>2005-10-05</title><class>dtstart</class>October 5</abbr><abbr><title>2005-10-08</title><class>dtend</class>7</abbr><class>url</class><span><class>summary</class>Web 2.0 Conference</span><span><class>location</class>Argent Hotel, San Francisco, CA</span></a><class>vevent</class></span>
FAIL
-------
<e><![CDATA[ .. some data .. ]]></e>
<e> .. some data .. </e>
FAIL
-------
<e><a /><![CDATA[ .. some data .. ]]><b /></e>
<e><a/><b/> .. some data .. </e>
FAIL
-------
<e>some text<![CDATA[ .. some data .. ]]>more text</e>
<e><array>some text</array><array> .. some data .. </array><array>more text</array></e>
FAIL
-------
<e>some text<![CDATA[ .. some data .. ]]><a /></e>
<e><a/>some text
 .. some data .. </e>
FAIL
-------
<e><![CDATA[ .. some data .. ]]><![CDATA[ .. more data .. ]]></e>
<e><array> .. some data .. </array><array> .. more data .. </array></e>
FAIL
-------
<e><![CDATA[ .. some data .. ]]><![CDATA[ .. & more data .. ]]></e>
<e><array> .. some data .. </array><array> .. &amp; more data .. </array></e>
FAIL
-------
<e><![CDATA[ .. some data .. ]]><![PCDATA[ .. &amp; still more data .. ]]></e>
error: rjx.main>>org.json.JSONException: Expected 'CDATA[' at 41 [character 42 line 1]

Is there a library, perhaps a fork of JSON-java, which can pass all the tests?

By the way, I can forgive the failures for order mismatch, that is within my specification, but structure changes are not.

  • If you want a conversion from XML to JSON that is truly lossless, even for mixed content, and even preserving whitespace, then the resulting JSON is going to be pretty unusable. That's why all conversion libraries I've come across (including the JS one that you cite) end up compromising between lossiness and usability. That's actually what most people want ("I can forgive...") but what lossiness is tolerable depends entirely on the XML vocabulary. For many use cases losing whitespace is quite acceptable, but not for all. – Michael Kay Apr 11 '18 at 19:46
  • @MichaelKay I'm not concerned with whitespace unless it is part of the CDATA/PCDATA, but the attributes are important to my implementation. – dacracot Apr 11 '18 at 22:33
  • That's precisely my point. Different people are concerned with different things, which is why it's so difficult to devise a solution that suits everybody. – Michael Kay Apr 11 '18 at 22:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.