[英]Deserializing multiple different tags (with the same name) with SimpleFramework
我正在使用用於XML序列化/反序列化的簡單框架,盡管第一個很容易,但是后者卻有問題。 因此,我從服務器收到XML響應,它看起來像這樣:
<?xml version="1.0" ?>
<tables>
<table name="result" a="context" b="name">
<r a="stuff1" b="blahblah" />
</table>
<table name="response" a="error" b="reason">
<r a="0" b="" />
</table>
</tables>
是的,它有2個名稱為“表”的元素。 問題在於,第一個“表”元素可能具有3個以上的屬性,這意味着,我不能只為“表”標簽創建通用實體。 因此,我當前的反序列化實體代碼如下所示:
@Root(name = "tables", strict = false)
public class Response {
@Element(name = "table", required = false)
@Path("//table[@name='result']")
Result resultTable;
@Element(name = "table")
@Path("//table[@name='result']")
Response responseTable;
public Result getResultTable() {
return resultTable;
}
public void setResultTable(Result resultTable) {
this.resultTable = resultTable;
}
public Response getResponseTable() {
return responseTable;
}
public void setResponseTable(Response responseTable) {
this.responseTable = responseTable;
}
}
不幸的是,它不起作用:我得到一個例外:
org.simpleframework.xml.core.PathException: Path '//[@name='result']' in field 'resultTable'
com.package.Response.resultTable references document root
我嘗試了不同的XPath選項,例如簡單的通配節點:
@Path("//*[@name='result']")
@Path("*[@name='result']")
但這也不起作用。 所以,是由於錯誤的XPath選項或Simple Framework的限制引起的我的錯:
使用此類注釋時要注意的一件事是,僅支持XPath表達式語法的子集。 例如,元素和屬性引用不能從文檔的根部獲取,僅允許當前上下文中的引用。
然后應該與其他XML反序列化器一起使用嗎? 謝謝。
您可以嘗試使用inline-list來解決此問題。 另一個-我認為更好的解決方案 :對於“如果名稱是將結果反序列化為結果,如果將響應反序列化為響應”部分,請使用Converter
。 這聽起來比實際要復雜得多!
由於有兩個Response
類-一個用於tables
,一個作為table
,我將后一個命名為ResponseTable
; ResultTable
在您的示例中為Result
。 我想您有一些軟件包來防止這種情況。
對於兩個表,都使用Content
類對<r ... />
元素進行建模。
@Root
public class ResponseTable // 'Response' in your code
{
@Attribute(name = "name")
private String name;
@Attribute(empty = "a")
private String a;
@Attribute(empty = "b")
private String b;
@Element(name = "r")
private Content r;
// ...
}
@Root
public class ResultTable // 'Result' in your code
{
@Attribute(name = "name")
private String name;
@Attribute(empty = "a")
private String a;
@Attribute(empty = "b")
private String b;
@Element(name = "r")
private Content r;
// ...
}
@Root()
public class Content
{
@Attribute(name = "a")
private String a;
@Attribute(name = "b")
private String b;
// ...
}
接下來是有趣的部分:
@Root(name = "tables", strict = false)
@Convert(Response.ResponseConverter.class)
public class Response
{
@Element(name = "table")
private ResultTable resultTable;
@Element(name = "table2")
private ResponseTable responeTable;
// ...
static class ResponseConverter implements Converter<Response>
{
private final Serializer ser = new Persister();
@Override
public Response read(InputNode node) throws Exception
{
Response resp = new Response();
InputNode n = node.getNext();
while( n != null )
{
switch( n.getAttribute("name").getValue() )
{
case "result":
resp.resultTable = ser.read(ResultTable.class, n);
break;
case "response":
resp.responeTable = ser.read(ResponseTable.class, n);
break;
default:
throw new RuntimeException("Unsupported table: "
+ n.getAttribute("name").getValue());
}
n = node.getNext();
}
return resp;
}
@Override
public void write(OutputNode node, Response value) throws Exception
{
// Implement as needed (hint: again use Serializer here)
throw new UnsupportedOperationException("Not supported yet.");
}
}
}
這里會發生什么:
@Convert
用於指定一個Converter
實現,該實現實現Response
類的(反)序列化 ResponseConverter
僅用於確定 <table …>…</table>
元素的類型 (= Response或Result表) Serializer
,使用常規的Serializer
器 -無需手動完成整個工作! 我尚未實現write()
部分,但是如您所見,它並不那么困難; 您可以再次使用Serializer
來完成主要工作。
Converter
: Response
Result
這樣就可以擁有多個序列化為xml的類,即使它們共享相同的元素名稱。
只需注意一件事:對於@Convert
,必須設置AnnotationStrategy
:
Serializer ser = new Persister(new AnnotationStrategy());
// ^^^^^^^^^^^^^^^^^^^^
final String xml = …
Response response = ser.read(Response.class, xml);
System.out.println(response)
注: 沒有必要使用一個AnnotationStrategy
你內的戰略Converter
-只要你不依賴於其他Converter
存在。
輸出量
(生成的toString()
方法)
Response{resultTable=ResultTable{name=result, a=context, b=name, r=Content{a=stuff1, b=blahblah}}, responeTable=ResponseTable{name=response, a=error, b=reason, r=Content{a=0, b=}}}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.