在Simple 2.5.3(Java)中反序列化重复的XML元素

时间:2011-06-01 06:37:04

标签: java xml xml-deserialization

假设给出了以下XML:

<?xml version="1.0" encoding="UTF-8"?>
<ResC>
    <Err text="Error text 1"/>
    <ConRes>
        <Err text="Error text 2"/>
        <ConList>
            <Err text="Error text 3"/>
            <Con>
                <Err text="Error text 4"/>
            </Con>
        </ConList>
    </ConRes>
</ResC>

正如您所看到的,<Err>元素可能出现在XML的每个级别上。

使用Simple我想反序列化这个XML。所以,我创建了以下类:

@Element(required=false)
public class Err {
    @Attribute
    private String text;

    public void setText(String text) { this.text = text; }

    public String getText() { return text; }
}

但是,如何为<ResC><ConRes><ConList><Con>添加类的注释?我是否真的必须在每个可能出现的类中声明类型为<Err>的属性?这似乎是很多开销。如果是这样,那么我必须检查每个对象是否包含错误。

有没有更好更简单的方法? : - )

谢谢,
罗伯特

1 个答案:

答案 0 :(得分:0)

要记住的重要一点是,Simple XML应该能够遵循您可以使用类逻辑生成的任何结构。因此,您可以创建一个使用错误接口的BaseClass并应用Decorator模式,以便将所有这些传递到具体的错误类,而不需要任何实现对象知道它们已经被赋予了什么。

这可能毫无意义。我只是告诉你......好吧......我刚刚离开并完全按照我的想法实现,这里是结果(full code link):

主文件:

package com.massaiolir.simple.iface;

import java.io.File;

import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;

public class Main {
    public static void main(String[] args) throws Exception {
        Serializer serial = new Persister();
        ResC resc = serial.read(ResC.class, new File("data/testdata.xml"));

        System.out.println(" == Printing out all of the error text. == ");
        System.out.println(resc.getErrorText());
        System.out.println(resc.conRes.getErrorText());
        System.out.println(resc.conRes.conList.getErrorText());
        for (Con con : resc.conRes.conList.cons) {
            System.out.println(con.getErrorText());
        }
        System.out.println(" == Finished printing out all of the error text. == ");
    }
}

它只是简单运行并显示结果。

BaseObject.java类:

package com.massaiolir.simple.iface;

import org.simpleframework.xml.Element;

public class BaseObject implements Error {
    @Element(name = "Err", required = false, type = ConcreteError.class)
    private Error err;

    @Override
    public String getErrorText() {
        return err.getErrorText();
    }

    @Override
    public void setErrorText(String errorText) {
        err.setErrorText(errorText);
    }
}

如果它想要'Err',这就是一切都应该扩展的类。

错误界面:

package com.massaiolir.simple.iface;

public interface Error {
    void setErrorText(String errorText);

    String getErrorText();
}

ConcreteError类:

package com.massaiolir.simple.iface;

import org.simpleframework.xml.Attribute;

public class ConcreteError implements Error {
    @Attribute
    private String text;

    @Override
    public String getErrorText() {
        return text;
    }

    @Override
    public void setErrorText(String errorText) {
        this.text = errorText;
    }

}

实际的实现类是在此之后。你会发现它们相当微不足道,因为真正的工作是在上面的课程中处理的。

Con类:

package com.massaiolir.simple.iface;

public class Con extends BaseObject {

}

ConList类:

package com.massaiolir.simple.iface;

import java.util.ArrayList;

import org.simpleframework.xml.ElementList;

public class ConList extends BaseObject {
    @ElementList(entry = "Con", inline = true)
    public ArrayList<Con> cons;
}

ConRes类:

package com.massaiolir.simple.iface;

import org.simpleframework.xml.Element;

public class ConRes extends BaseObject {
    @Element(name = "ConList")
    public ConList conList;
}

ResC课程:

package com.massaiolir.simple.iface;

import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root;

@Root
public class ResC extends BaseObject {
    @Element(name = "ConRes")
    public ConRes conRes;
}

这就是它的全部内容。非常简单吧。我能够在十分钟内全力以赴。写这个回复实际上花了我更长的时间,而不是我编写我给你的代码。如果您对我刚刚编写的代码一无所知,请告诉我。我希望这有助于你了解如何做这样的事情。