Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple Xml - order of elements not preserved?‏

I am using SimpleXml 2.6.1 in my android app. Eventhough the documentation (http://simple.sourceforge.net/download/stream/doc/javadoc/index.html?org/simpleframework/xml/Order.html) says the order of the elements in the xml are same as the way they have defined in the class file, I am always getting the order to be random in the xml. If I add few more variables, the order of the elements again changes.

Adding @Order notation works, but since the class is complex with 100s of variables, I do not want to add order. Is this a known bug for android versions? It works fine in java console programs.

p.s: I opened the .class file disassembled and found the variables declared in the same order as java file, so I don't think it's a class file issue.

like image 649
bschandramohan Avatar asked Sep 29 '11 05:09

bschandramohan


People also ask

Does XML preserve order?

XML element comparison by default preserves the order of elements in the two documents.

Does XML care about the order of elements?

In the most general sense, XML element order does not matter, unless otherwise specified by the appropriate schema.

Does order matter in build XML?

XML Specification Generally speaking, the order in which child elements appear inside their parent element container in XML shouldn't matter. As such, the following two examples would be considered semantically equivalent XML.

Is XML order dependent?

Element order is significant in XML. The grammar implies that element ordering is significant, but, unlike for attributes, there is no explicit statement regarding the significance of the order of elements.


2 Answers

import org.simpleframework.xml.Element;    
import org.simpleframework.xml.Order;

    @Order(elements = {"name", "isTrue"})
    public class SimpleXml {

        public static final String NAME = "$NAME$";
        public static final String IS_TRUE = "$IS_TRUE$";

        @Element
        private String name;

        @Element
        private Boolean isTrue;
    ...
like image 59
autopilot Avatar answered Sep 30 '22 17:09

autopilot


Since there is no answer, I'll try to save precious time to anyone who gets here.

I found no cause, and since I don't have time to analyze Simple libraries, I came up with a "workaroud". It's more of an advice, actually - don't use it for (marshaling)creating xml if you have a large xml definition and the order matters(a rule more than an exception). The order is mostly used for marshaling anyway so just save yourself some time and do it manually.

The template:

<document>
    <name>$NAME$</name>
    <isTrue>$IS_TRUE$</isTrue>
</document>

The class:

import org.apache.commons.io.IOUtils;

import java.io.IOException;
import java.io.InputStream;

/**
 * User: ksaric
 */

public class SimpleXml {

    public static final String NAME = "$NAME$";
    public static final String IS_TRUE = "$IS_TRUE$";

    private String name;
    private Boolean isTrue;

    public SimpleXml() {
    }

    public Boolean getTrue() {
        return isTrue;
    }

    public void setTrue(Boolean aTrue) {
        isTrue = aTrue;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        String template = null;

        try {
            template = getTemplate();
        } catch (IOException e) {
            e.printStackTrace();
        }

        /* GUAVA - checkNotNull() */
        if (null == template) return null;

        template = template.replace(NAME, getName());

        /* OR CONVERT IN THE GETTER METHOD */
        template = template.replace(IS_TRUE, getTrue().toString());

        return template;
    }

    /* SINGLETON? Performance(IO) loss... */
    public String getTemplate() throws IOException {
        InputStream templateStream = getClass().getResourceAsStream("/template.xml");

        /* APACHE IO COMMONS */

        /*
         <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-io</artifactId>
            <version>1.3.2</version>
        </dependency>
         */

        final String stringTemplate = IOUtils.toString(templateStream);

        return stringTemplate;
    }
}

The test:

import org.junit.Test;

import static junit.framework.Assert.*;

/**
 * User: ksaric
 */

public class SimpleXmlTest {

    @Test
    public void test() throws Exception {
        //Before

        /* Use standard instantiation, factory method recommended for immutability */
        SimpleXml simpleXml = new SimpleXml();
        simpleXml.setName("This is a name");
        simpleXml.setTrue(false);

        //When
        String result = simpleXml.toString();

        //Then
        assertNotNull(result);
        System.out.println(result);
    }
}

Not really an answer, but save yourself some time and don't use Simple(which is a great library) on Android...

like image 25
pfh Avatar answered Sep 30 '22 19:09

pfh