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 disas开发者_如何学编程sembled and found the variables declared in the same order as java file, so I don't think it's a class file issue.
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;
...
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...
Simple Xml doesn't preserve Order on Android. Based on pfh's answer, here is my recommendation: I would prefer to use JAXB in the case where you want the order to be preserved than manual string/template parsing. JAXB is slightly complex to use than SimpleXml but comes with similar set of annotations based xml serialization and deserialization.
精彩评论