我正在使用 Retrofit 和 SimpleXMLConverter 来获取和反序列化 XML 文件。我正在将属性转换为长类型。如果属性有时不是“”,也就是空的,它会正常工作。
我尝试使用
@Attribute(empty="-1")
对于这种情况,这个属性应该是空的,所以它应该返回“-1”,但它没有这样做。这个空属性的用法是否正确?
我正在使用 Retrofit 和 SimpleXMLConverter 来获取和反序列化 XML 文件。我正在将属性转换为长类型。如果属性有时不是“”,也就是空的,它会正常工作。
我尝试使用
@Attribute(empty="-1")
对于这种情况,这个属性应该是空的,所以它应该返回“-1”,但它没有这样做。这个空属性的用法是否正确?
如果属性有时不是“”,也就是空的,它会正常工作。
这在这里是不正确的:属性值 - 被视为字符串 -在缺失或“无”的含义中不是空的,它是一个空字符串。
这是一个例子:
XML:
<root value=""></root>
Java类:
@Root(name = "root")
public class Example
{
@Attribute(name = "value", empty = "-1", required = false)
private long value;
@Override
public String toString()
{
return "Example{" + "value=" + value + '}';
}
}
这会抛出 - 这是合理的 - 一个NumberFormatException
. 如果将类型替换为value
不会String
捕获异常,值将设置为空字符串( ""
)。另一方面,保留字符串类型但删除 XML 中的属性将设置"-1"
为值(这required = false
就是使用的原因)。现在序列化器找不到任何值,因此设置了默认值。
你可以在你的类内部处理这个,比如让相应的getter方法-1
在空字符串的情况下返回:
public long getValue()
{
if( value == null || value.isEmpty() == true )
{
return -1;
}
return Long.valueOf(value);
}
(不要忘记根据这个更改您的代码 - 在我的示例中,您必须更改toString()
-method)
但是有一个更好的解决方案:Simple 允许您为任何类型实现自定义Transformer(不要混用Converter
!)。有了这些,您可以根据需要实现type -> String
(写入)和String -> type
(读取)。
根据我上面的示例,这是一个实现:
public class LongTransformer implements Transform<Long>
{
// Default value which is set if no / empty input is available
private final long defaultValue;
public LongTransformer(long defaultValue)
{
this.defaultValue = defaultValue;
}
public LongTransformer()
{
this(-1); // Just in case you always have -1 as default
}
@Override
public Long read(String value) throws Exception
{
// If there's no or an empty String the default value is returned
if( value == null || value.isEmpty() == true )
{
return defaultValue; //
}
return Long.valueOf(value); // Return the value
}
@Override
public String write(Long value) throws Exception
{
/*
* Nothing special here. In case you you need a empty string if
* value = -1, you can do it here.
*/
return value.toString();
}
}
最后是一个如何使用的例子。关键部分介于两行之间:
final String xml = "<root value=\"\">\n"
+ "</root>";
// ---------------------------------------------------------------------
final LongTransformer numberTransformer = new LongTransformer(-1);
RegistryMatcher m = new RegistryMatcher();
m.bind(long.class, numberTransformer);
Serializer ser = new Persister(m);
// ---------------------------------------------------------------------
Example root = ser.read(Example.class, xml);
System.out.println(root);
输出:
Example{value=-1}
@vandus,这是我到目前为止所做的:我在 Main onCreate 类中创建了一个适配器,我作为 List 传入的模型是 XML 文件的根节点:http: //www.w3schools.com// xml/simple.xml
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint("http://www.w3schools.com")
.setConverter(new SimpleXMLConverter())
.build();
GitHubService foodService = restAdapter.create(GitHubService.class);
List<BreakfastMenu> repos = foodService.getFile();
repos.toString();
public interface GitHubService
{
@GET("/xml/simple.xml")
List<BreakfastMenu> getFile();
}