2012-01-15 14 views
5

Tengo dos clases que tienen relaciones entre sí como se muestra a continuación. Tengo una lista de objetos ObjReal donde se presentan todos los datos. Quiero guardar toda la lista en xml sin perder las relaciones de objeto. Quiero decir que un objeto representado en XML debería tener sus objStrucs correspondientes junto con él. Para almacenar ObjReal en xml es sencillo pero me confundo con sus relaciones ObjStruc. Por favor, ayuda para resolver este problema.¿Cómo puedo almacenar ArrayList de objetos complejos en xml?

Mi ObjReal es:

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; 
    } 

} 

Mi ObjStruc es:

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

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

} 

Y los datos completa se encuentra en ArrayList<ObjReal> obreals objeto que quiero volcar en XML. Espero haber mantenido un punto claro. Gracias por adelantado.

Respuesta

2

¡Sólo aliméntelo a XStream! Funciona en ambos sentidos. Fragmentos de código here. ¡Buena suerte!

3

Hay varias bibliotecas que serializarán las estructuras de objetos en xml. Uno de ellos es XStream. Hay un tutorial fácil y rápido here.

+0

Muy interesante ... ¡Voy a votar esto! – aviad

0
+0

IMO, JAXB está un poco desactualizado y no es tan útil e intuitivo como otros (XStream) – aviad

+2

+1 para JAXB (no estoy seguro de por qué @aviad down lo votó).Aquí hay un artículo que escribí comparando JAXB y XStream: http://blog.bdoughan.com/2010/10/how-does-jaxb-compare-to-xstream.html. Aquí hay otro artículo que escribí que demuestra algunas cosas nuevas y emocionantes que se están haciendo en EclipseLink JAXB (soy el líder tecnológico): http://blog.bdoughan.com/2011/09/mapping-objects-to-multiple-xml -schemas.html –

+0

@Blaise Doughan gracias por su comentario y por compartir el enlace a su blog. ¡Muy interesante! – aviad

4

Nota: Soy el líder EclipseLink JAXB (MOXy) y miembro de JAXB 2 (JSR-222) grupo de expertos.

hay un par de aspectos interesantes de su caso de uso:

  1. ArrayList como el objeto raíz
  2. relación bidireccional entre ObjReal y ObjStruc

1. arrayList AS objeto raíz

Implementaciones JAXB (MOXy, Metro, Ja xMe, etc.) no proporcionan soporte directo para manejar tipos Collection como objetos raíz. Para manejar este caso de uso, simplemente necesita crear una clase contenedora que tenga el Collection deseado como un campo/propiedad.

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

    private ArrayList<ObjReal> objReals;   

} 

2. BIDIRECCIONAL RELATIOSNHIP

Usted puede usar la extensión @XmlInverseReference en la implementación de EclipseLink JAXB para manejar la relación bidireccional en su modelo. A continuación he incluido un ejemplo completo. He omitido la mayoría de los métodos de acceso para ahorrar espacio.

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

La anotación @XmlInverseReference se utiliza en esta clase. En esta anotación se especifica el nombre cado/Propiedad en el otro sentido de la relación:

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

Para especificar moxy como su proveedor de JAXB es necesario incluir un archivo llamado jaxb .properties con el siguiente contenido en el mismo paquete que sus clases de dominio:

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

demostración

puede ejecutar el siguiente código para verificar la correspondencia:

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); 
    } 

} 

de entrada (input.xml)

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

salida

A continuación se muestra la salida de ejecutando el código de demostración. Como se puede ver la propiedad objReal en cada uno de los ObjStruc objetos fue poblada durante el unmarshal:

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

Para más información

Descargar EclipseLink

Puede descargar EclipseLink en:

1

Cualquier forma sencilla de escribir un objeto de Java para XML es utilizar el codificador java xml . Esto escribe su objeto completo y sus dependencias en formato xml. Luego puede leerlos nuevamente en su objeto también.

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; 
} 
Cuestiones relacionadas