ryv*_*ron 2 android converter xml-parsing 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(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
}
Run Code Online (Sandbox Code Playgroud)
LeagueConverter.java:
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.");
}
}
Run Code Online (Sandbox Code Playgroud)
XML的例子:
<android>
<leagues>
<league name ="A">
<Headlines></Headlines>
<Scores></Scores>
...
</league>
<league name ="B">...</league>
</leagues>
</android>
Run Code Online (Sandbox Code Playgroud)
我是如何调用它并期望它表现的:(片段)
Android android = null;
Serializer serial = new Persister(new AnnotationStrategy());
android = serial.read(Android.class, source);
Log.i("Number of leagues found ",tsnAndroid.getLeagueCount() + ""); // prints fine
League nhl = tsnAndroid.getLeagues().get(0); // works fine
// DOES NOT WORK throws NullPointerEx
League nhl2 = tsnAndroid.getLeagueByName("A");
// DOES NOT WORK throws NullPointerEx
for(String s : nhl.getOrder())
{
Log.i("ORDER>>>>>", s);
}
Run Code Online (Sandbox Code Playgroud)
问题:
android.getLeagueByName()(使用@Attribute名称)当我有转换器设置时突然停止工作,所以它像下面这样League.java,永远不会被设置.
@Attribute
private String name; // not being set
Run Code Online (Sandbox Code Playgroud)
然而,当我在转发器声明中注释掉League.java- 每个联盟都有一个名为name的属性并且android.getLeagueByName()开始正常工作......
@Convert for League是否会以某种方式干扰联盟中的@Attribute?
小智 5
虽然这个问题非常古老(就像SimpleXML库一样),但我会给出两分钱.
@Convert注释仅适用于@Element,但它对@Attribute没有任何影响.我不确定这是一个错误还是一个功能,但还有另一种处理自定义序列化对象的方法 - 名为Transform with Matcher,它既适用于Attributes,也适用于Elements.您可以定义一个处理序列化和反序列化的Transform类,而不是使用Converter ;
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;
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,它比实现Convert接口更直接!
为需要自定义de/serialization的所有对象创建一个类似的类.
现在实例化一个RegistryMatcher对象,并在其中注册您的自定义类及其相应的Transform类.这是一个内部使用缓存的线程安全对象,因此将其保留为单例可能是个好主意.
private static final RegistryMatcher REGISTRY_MATCHER = new RegistryMatcher();
static {
try {
REGISTRY_MATCHER.bind(UUID.class, UUIDTransform.class);
// register all your Transform classes here...
} catch (Exception e) {
throw new RuntimeException(e);
}
}
Run Code Online (Sandbox Code Playgroud)
最后,您可以在每次转换之前创建一个Persister类,并将AnnotationStrategy与RegistryMatcher实例一起传递给它.在下面的工厂方法中,我们还将使用缩进格式化程序:
private static Persister createPersister(int indent) {
return new Persister(new AnnotationStrategy(), REGISTRY_MATCHER, new Format(indent));
}
Run Code Online (Sandbox Code Playgroud)
现在您可以进行序列化/反序列化方法:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
这种方法的唯一问题是当你想要为同一个对象设置不同的格式时 - 例如,一旦你希望java.util.Date只有日期组件,稍后你也想拥有时间组件.然后只需扩展Date类,将其命名为DateWithTime,并为其创建不同的Transform.
| 归档时间: |
|
| 查看次数: |
1811 次 |
| 最近记录: |