Как я могу сохранить ArrayList сложных объектов в XML? - PullRequest
5 голосов
/ 15 января 2012

У меня есть два класса, которые имеют отношения друг с другом, как показано ниже. У меня есть список объектов ObjReal, где представлены все данные. Я хочу сохранить весь список в 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 ]

4 голосов
/ 15 января 2012

Примечание: Я EclipseLink JAXB (MOXy) и являюсь членом JAXB 2 (JSR-222 ) экспертная группа.

В вашем случае есть пара интересных аспектов:

  1. ArrayList в качестве корневого объекта
  2. Двунаправленная связь между ObjReal и ObjStruc

1. ARRAYLIST КАК ОБЪЕКТ КОРНИ

Реализации JAXB (MOXy, Metro, JaxMe и т. Д.) Не предоставляют прямой поддержки для обработки типов Collection как корневых объектов. Чтобы справиться с этим вариантом использования, вам просто нужно создать класс-оболочку с желаемым Collection в качестве поля / свойства.

@XmlRootElement(name="root-element-name")
@XmlAccessorType(XmlAccessType.FIELD)
public class ListWrapper {

    private ArrayList<ObjReal> objReals;        

}

2. Двунаправленное отношение

Вы можете использовать расширение @XmlInverseReference в реализации EclipseLink JAXB для обработки двунаправленных отношений в вашей модели. Ниже я включил полный пример. Я опустил большинство методов доступа для экономии места.

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 / свойства для другого направления отношения:

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 по адресу:

3 голосов
/ 15 января 2012

Есть несколько библиотек, которые будут сериализовывать структуры объектов в xml. Одним из них является XStream . Здесь есть простой и быстрый учебник .

2 голосов
/ 15 января 2012

Просто введите XStream ! Это работает в обе стороны. Фрагменты кода здесь . Удачи!

1 голос
/ 15 января 2012

Любой простой способ написать объект Java в XML - это использовать кодировщик Java Java. Это записывает весь ваш объект и его зависимости в формате 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;
}
0 голосов
/ 15 января 2012

JAXB ( Java Architecture для привязки XML ), возможно, является идеальным способом преобразования объектов Java в XML и их извлечения обратно:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...