Android-简单的XML框架@Convert会干扰@Attribute-如何解决此问题?
我正在努力捕捉标签中包含的元素的顺序。以下是所有代码: League.java:Android-简单的XML框架@Convert会干扰@Attribute-如何解决此问题?,android,xml-parsing,converter,simple-framework,Android,Xml Parsing,Converter,Simple Framework,我正在努力捕捉标签中包含的元素的顺序。以下是所有代码: League.java: @Root @Convert(value = LeagueConverter.class) public class League { @Attribute private String name; @Element(name="headlines", required = false) private Headlines headlines; @Element(nam
@Root
@Convert(value = LeagueConverter.class)
public class League
{
@Attribute
private String name;
@Element(name="headlines", required = false)
private Headlines headlines;
@Element(name="scores", required = false)
private Scores scores;
@Element(name="standings", required = false)
private Standing standings;
@Element(name="statistics", required = false)
private LeagueStatistics statistics;
public List<String> order = new ArrayList<String>();
// get methods for all variables
}
public class LeagueConverter implements Converter<League>
{
@Override
public League read(InputNode node) throws Exception
{
League league = new League();
InputNode next = node.getNext();
while( next != null )
{
String tag = next.getName();
if(tag.equalsIgnoreCase("headlines"))
{
league.order.add("headlines");
}
else if(tag.equalsIgnoreCase("scores"))
{
league.order.add("scores");
}
else if(tag.equalsIgnoreCase("statistics"))
{
league.order.add("statistics");
}
else if(tag.equalsIgnoreCase("standings"))
{
league.order.add("standings");
}
next = node.getNext();
}
return league;
}
@Override
public void write(OutputNode arg0, League arg1) throws Exception
{
throw new UnsupportedOperationException("Not supported yet.");
}
}
<android>
<leagues>
<league name ="A">
<Headlines></Headlines>
<Scores></Scores>
...
</league>
<league name ="B">...</league>
</leagues>
</android>
问题:
@Root
@Convert(value = LeagueConverter.class)
public class League
{
@Attribute
private String name;
@Element(name="headlines", required = false)
private Headlines headlines;
@Element(name="scores", required = false)
private Scores scores;
@Element(name="standings", required = false)
private Standing standings;
@Element(name="statistics", required = false)
private LeagueStatistics statistics;
public List<String> order = new ArrayList<String>();
// get methods for all variables
}
public class LeagueConverter implements Converter<League>
{
@Override
public League read(InputNode node) throws Exception
{
League league = new League();
InputNode next = node.getNext();
while( next != null )
{
String tag = next.getName();
if(tag.equalsIgnoreCase("headlines"))
{
league.order.add("headlines");
}
else if(tag.equalsIgnoreCase("scores"))
{
league.order.add("scores");
}
else if(tag.equalsIgnoreCase("statistics"))
{
league.order.add("statistics");
}
else if(tag.equalsIgnoreCase("standings"))
{
league.order.add("standings");
}
next = node.getNext();
}
return league;
}
@Override
public void write(OutputNode arg0, League arg1) throws Exception
{
throw new UnsupportedOperationException("Not supported yet.");
}
}
<android>
<leagues>
<league name ="A">
<Headlines></Headlines>
<Scores></Scores>
...
</league>
<league name ="B">...</league>
</leagues>
</android>
当我设置了转换器时,android.getLeagueByName()
(与@Attribute
name一起使用)突然停止工作,因此它就像League.java
中的以下内容一样,从未设置过
@Attribute
private String name; // not being set
但是,当我在League.java
中注释掉转换器声明时,每个League都有一个名为name的属性,并且android.getLeagueByName()
开始正常工作
Convert for League是否在某种程度上干扰了League中的@Attribute?
@Convert
注释仅对@Element
字段有效。我也在努力转换@Attribute
字段,但目前还没有成功…尽管这个问题已经非常老了(就像SimpleXML库一样),我还是愿意付出我的两分钱
@Convert注释仅适用于@元素,但对@属性没有任何影响。我不确定这是一个bug还是一个特性,但有另一种处理自定义序列化对象的方法-使用匹配器称为转换,它既可以使用属性,也可以使用元素。您可以定义一个处理序列化和反序列化的转换类,而不是使用转换器s:
import java.util.UUID;
import org.simpleframework.xml.transform.Transform;
public class UUIDTransform implements Transform<UUID> {
@Override
public UUID read(String value) throws Exception {
return value != null ? UUID.fromString(value) : null;
}
@Override
public String write(UUID value) throws Exception {
return value != null ? value.toString() : null;
}
}
最后,您可以在每次转换之前创建一个持久化器类,并将注释策略与您的注册表匹配器实例一起传递给它。在下面的工厂方法中,我们还将使用缩进格式化程序:
private static Persister createPersister(int indent) {
return new Persister(new AnnotationStrategy(), REGISTRY_MATCHER, new Format(indent));
}
现在,您可以创建序列化/反序列化方法:
public static String objectToXml(Object object, int indent) throws MyObjectConversionException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
Persister p = createPersister(indent);
try {
p.write(object, out, "UTF-8");
return out.toString("UTF-8");
} catch (Exception e) {
throw new MyObjectConversionException("Cannot serialize object " + object + " to XML: " + e.getMessage(), e);
}
}
public static <T> T xmlToObject(String xml, final Class<T> clazz) throws MyObjectConversionException {
Persister p = createPersister(0);
try {
return (T) p.read(clazz, xml);
} catch (Exception e) {
throw new MyObjectConversionException(
"Cannot deserialize XML to object of type " + clazz + ": " + e.getMessage(), e);
}
}
公共静态字符串objectToXml(对象对象,int缩进)抛出MyObjectConversionException{
ByteArrayOutputStream out=新建ByteArrayOutputStream();
持久器p=创建持久器(缩进);
试一试{
p、 写入(对象,输出,“UTF-8”);
返回。toString(“UTF-8”);
}捕获(例外e){
抛出新的MyObjectConversionException(“无法将对象”+object+”序列化为XML:+e.getMessage(),e);
}
}
公共静态T xmlToObject(字符串xml,最终类clazz)抛出MyObjectConversionException{
Persister p=createPersister(0);
试一试{
return(T)p.read(clazz,xml);
}捕获(例外e){
抛出新的MyObjectConversionException(
无法将XML反序列化为“+clazz+”类型的对象:“+e.getMessage(),e);
}
}
这种方法的唯一问题是,当您希望对同一对象使用不同的格式时,例如,您希望java.util.Date只包含日期组件,而以后您还希望包含时间组件。然后只需扩展Date类,调用它DateWithTime,并对其进行不同的转换。getLeagueByName()的作用是什么?您是否检查了您的联盟列表是否包含任何非空值?可能列表中的元素计数正确,但所有元素都
null
。我刚刚检查了联赛返回的内容。当我注释掉@convert-leagues本身时,似乎是空的,因为android元素没有解析。但是我不知道为什么。您可以调试每个反序列化(每个对象),可能只有一个失败并导致null
。这不是只有在联合中的所有元素都是元素列表时才起作用吗?不正确。简单xml也允许在类级别上使用@Convert。