如何将复杂对象的ArrayList存储到xml中?

时间:2012-01-15 07:58:36

标签: java xml arraylist

我有两个相互关系的课程,如下所示。我有一个ObjReal对象列表,其中显示了整个数据。我想将整个List保存到xml而不会丢失对象关系。我的意思是用XML表示的对象应该有它们对应的objStrucs。         将ObjReal存储到xml中是直截了当的,但我对它的ObjStruc关系感到困惑。请帮助解决这个问题。

我的ObjReal是:

Class ObjReal
{
  private String id;
  private String data;

  ArrayList<ObjStruc> objStrucs=new ArrayList<ObjStruc>();

  public ArrayList<ObjStruc> getObjStrucs()
    {
        return objStrucs;
    }

  public String getId()
 {
      return id;
 }

  public String getData()
    {
      return data;
    }

    public void setId(String id)
    {
        this.id=id;
    }
    public void setData(String data)
    {
        this.data=data;
    }

}

我的ObjStruc是:

Class ObjStruc
{
    private ObjReal objReal;
    public ObjReal getObjReal()
 {
      return objReal;
 }

  public ObjReal setObjReal(ObjReal objReal)
    {
      this.objReal=objReal;
    }

}

完整的数据在ArrayList<ObjReal> obreals对象中,我想将其转储到xml中。我希望我明确指出。提前谢谢。

5 个答案:

答案 0 :(得分:4)

注意:我是EclipseLink JAXB (MOXy)主管,是JAXB 2 (JSR-222)专家组的成员。

您的用例有几个有趣的方面:​​

  1. ArrayList作为根对象
  2. ObjRealObjStruc
  3. 之间的双向关系

    <强> 1。 ARRAYLIST作为根目标

    JAXB实现(MOXy,Metro,JaxMe等)不提供对作为根对象处理Collection类型的直接支持。要处理此用例,您只需创建一个包含所需Collection作为字段/属性的包装类。

    @XmlRootElement(name="root-element-name")
    @XmlAccessorType(XmlAccessType.FIELD)
    public class ListWrapper {
    
        private ArrayList<ObjReal> objReals;        
    
    }
    

    <强> 2。双向关系

    您可以在JAXB的EclipseLink实现中使用@XmlInverseReference扩展来处理模型中的双向关系。下面我列出了一个完整的例子。我省略了大多数存取方法来节省空间。

    <强> ObjReal

    import java.util.ArrayList;
    import javax.xml.bind.annotation.*;
    
    @XmlRootElement
    @XmlAccessorType(XmlAccessType.FIELD)
    class ObjReal {
    
      private String id;
      private String data;
      ArrayList<ObjStruc> objStrucs=new ArrayList<ObjStruc>();
    
      public ArrayList<ObjStruc> getObjStrucs() {
        return objStrucs;
      }
    
    }
    

    <强> ObjStruc

    此类使用@XmlInverseReference注释。在此注释上,您可以为关系的另一个方向指定fied / property名称:

    import javax.xml.bind.annotation.*;
    import org.eclipse.persistence.oxm.annotations.XmlInverseReference;
    
    @XmlAccessorType(XmlAccessType.FIELD)
    class ObjStruc {
    
        @XmlInverseReference(mappedBy="objStrucs")
        private ObjReal objReal;
    
        public ObjReal getObjReal() {
            return objReal;
        }
    
    }
    

    jaxb.properties

    要将MOXy指定为JAXB提供程序,您需要在域类中包含一个名为 jaxb.properties 的文件,其中包含以下内容:

    javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
    

    <强>演示

    您可以运行以下代码来验证映射:

    import java.io.File;
    import javax.xml.bind.*;
    
    public class Demo {
    
        public static void main(String[] args) throws Exception  {
            JAXBContext jc = JAXBContext.newInstance(ObjReal.class);
    
            Unmarshaller unmarshaller = jc.createUnmarshaller();
            File xml = new File("src/forum8868303/input.xml");
            ObjReal objReal = (ObjReal) unmarshaller.unmarshal(xml);
    
            for(ObjStruc objStruc : objReal.getObjStrucs()) {
                System.out.println(objStruc.getObjReal());
            }
    
            Marshaller marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(objReal, System.out);
        }
    
    }
    

    输入(input.xml)

    <?xml version="1.0" encoding="UTF-8"?>
    <objReal>
        <id>123</id>
        <data>some data</data>
        <objStrucs/>
        <objStrucs/>
    </objReal>
    

    <强>输出

    以下是运行演示代码的输出。如您所见,在解组期间填充了每个objReal对象上的ObjStruc属性:

    forum8868303.ObjReal@7f712b3a
    forum8868303.ObjReal@7f712b3a
    <?xml version="1.0" encoding="UTF-8"?>
    <objReal>
       <id>123</id>
       <data>some data</data>
       <objStrucs/>
       <objStrucs/>
    </objReal>
    

    了解更多信息

    下载EclipseLink

    您可以在以下网址下载EclipseLink:

答案 1 :(得分:3)

有几个库将对象结构序列化为xml。其中一个是XStream。有一个简单快速的教程here

答案 2 :(得分:2)

只需将其提供给XStream! 它有两种方式。 代码段here。 祝你好运!

答案 3 :(得分:1)

将java对象写入xml的任何简单方法都是使用java xml编码器。这会将整个对象及其依赖项写入xml格式。然后,您也可以将它们读回您的对象。

public static boolean writeXMLFile(final Object data, final String fileName) {

    XMLEncoder encoder = null;

    boolean result = true;

    try {
        encoder = new XMLEncoder(new BufferedOutputStream(new FileOutputStream(fileName)));
        encoder.writeObject(data);
    } catch (final IOException e) {
        logger.error(e.getMessage());
        result = false;
    } finally {
        if (encoder != null) {
            encoder.close();
        } else {
            result = false;
        }
    }

public static Object readXMLFile(final String fileName) {

    XMLDecoder decoder = null;
    Object data = null;

    try {
        FileInputStream fis = new FileInputStream(fileName);
        BufferedInputStream bis = new BufferedInputStream(fis);
        decoder = new XMLDecoder(bis);
        data = decoder.readObject();
    } catch (final FileNotFoundException e) {
        data = null;
        logger.error(e.getMessage());
    } catch (final Exception e) {
        data = null;
        logger.error(e.getMessage());
    } finally {
        if (decoder != null) {
            decoder.close();
        } else {
            data = null;
        }
    }

    return data;
}

答案 4 :(得分:0)