SimpleFramwork XML:具有内部文本和子元素的元素 [英] SimpleFramwork XML: Element with Inner Text and Child Elements
问题描述
在使用无法更改的特定格式的SimpleFramework反序列化xml时,我有以下情况...
I have the following situtation in deserializing xml using SimpleFramework of specific format that cannot be changed...
<Question ID="Q1">
THIS INNER TEXT IS THE ISSUE
<Criteria Type="Normal" Source="OEM">
<Value Type="0">45.7</Value>
<Value Type="100">42.7</Value>
</Criteria>
<Criteria Type="Impact" Source="OEM">
<Value Type="0">45.7</Value>
<Value Type="100">42.7</Value>
</Criteria>
<!-- CRITERIA CAN HAVE ANY NUMBER -->
</Question>
这是我为问题撰写的课程
and here is the class I wrote for Question
@Root (name="Question")
public class Question {
@Attribute (name="ID")
private String id;
@ElementList (inline=true, required=false)
private List<Criteria> criteria;
@Text
private String text;
// And their getter and setters...
}
现在的问题是,我无法获取内部文本...
有人可以建议我做这件事的方法吗... ???
Can anybody suggest me the way to do this...???
推荐答案
您不能在此处使用@Text
批注,只有在您没有孩子的情况下,这才有可能.
You can't use @Text
annotation here, this is only possible if you don't have any child.
及其[
@Text
批注]不能与另一个XML元素批注一起出现,例如 作为Element
注释.
and it [
@Text
annotation] can not appear with the another XML element annotations, such as theElement
annotation.
来源: @Text
API文档
但是,您可以对这些文本使用Converter
.这有点棘手,但这是一个示例:
However, you can use a Converter
to those text. This is a bit tricky, but here's an example:
@Root(name = "Criteria")
public class Criteria
{
@Attribute(name = "Type")
private String type;
@Attribute(name = "Source")
private String source;
@ElementList(name = "Values", inline = true)
private ArrayList<Value> values;
public Criteria(String type, String source)
{
this.type = type;
this.source = source;
this.values = new ArrayList<>();
}
private Criteria() { }
// ...
@Override
public String toString()
{
return "Criteria{" + "type=" + type + ", source=" + source + ", values=" + values + '}';
}
// Inner class for values - you also can use a normal one instead
@Root(name = "Value")
public static class Value
{
@Attribute(name = "Type", required = true)
private int type;
@Text(required = true)
private double value;
public Value(int type, double value)
{
this.type = type;
this.value = value;
}
private Value() { }
}
}
Question
类:
Question
class:
@Root(name = "Question")
@Convert( value = Question.QuestionConvert.class)
public class Question
{
@Attribute(name = "ID", required = true)
private String id;
@Element(name = "text")
private String text;
@ElementList(inline = true)
private ArrayList<Criteria> criteria;
public Question(String id)
{
this.id = id;
this.criteria = new ArrayList<>();
this.text = "This inner text ...";
}
private Question() { }
// ...
@Override
public String toString()
{
return "Question{" + "id=" + id + ", text=" + text + ", criteria=" + criteria + '}';
}
static class QuestionConvert implements Converter<Question>
{
private final Serializer ser = new Persister();
@Override
public Question read(InputNode node) throws Exception
{
Question q = new Question();
q.id = node.getAttribute("ID").getValue();
q.text = node.getValue();
q.criteria = new ArrayList<>();
InputNode criteria = node.getNext("Criteria");
while( criteria != null )
{
q.criteria.add(ser.read(Criteria.class, criteria));
criteria = node.getNext("Criteria");
}
return q;
}
@Override
public void write(OutputNode node, Question value) throws Exception
{
node.setAttribute("ID", value.id);
node.setValue(value.text);
for( Criteria c : value.getCriteria() )
{
ser.write(c, node);
}
}
}
}
请注意所有那些空的构造函数.简单来说,它们是必需的,但是您可以将它们设为私有.您不必将那些内部类实现为内部类.
Please note all those empty constructors. They are required by simple but you can keep them private. You don't have to implement those inner classes as inner.
解决方案的关键是Converter
,它允许您一起使用 text 和 child-elements .您可以使用Serializer
编写所有Criteria
-childs.
The key to the solution is the Converter
which allows you to use text and child-elements together. You can use a Serializer
to write all the Criteria
-childs.
有些toString()
方法仅用于测试-您可以根据需要实现它们.
There are some toString()
methods, those are only for testing - you can implement them as you need.
输入XML:
<Question ID="Q1">This inner text ...
<Criteria Type="Normal" Source="OEM">
<Value Type="0">45.7</Value>
<Value Type="100">42.7</Value>
</Criteria>
<Criteria Type="Impact" Source="OEM">
<Value Type="0">45.7</Value>
<Value Type="100">42.7</Value>
</Criteria>
</Question>
示例代码:
Serializer ser = new Persister(new AnnotationStrategy()); // Don't miss the AnnotationStrategy!
Question q = ser.read(Question.class, f);
System.out.println(q);
输出:
Question{id=Q1, text=This inner text ...
, criteria=[Criteria{type=Normal, source=OEM, values=[Value{type=0, value=45.7}, Value{type=100, value=42.7}]}, Criteria{type=Impact, source=OEM, values=[Value{type=0, value=45.7}, Value{type=100, value=42.7}]}]}
不是很漂亮,但是可以正常工作! :-)
Not very beautiful, but it's working! :-)
Ps.由于Converter的两种方法都已实现,因此您还可以使用此代码序列化Question
对象.
Ps. Since both methods of the Converter are implemented you also can use this code to serialize a Question
object.
这篇关于SimpleFramwork XML:具有内部文本和子元素的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!