SimpleFramwork XML:具有内部文本和子元素的元素 [英] SimpleFramwork XML: Element with Inner Text and Child Elements

查看:111
本文介绍了SimpleFramwork XML:具有内部文本和子元素的元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用无法更改的特定格式的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 the Element 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆