2010-09-10 28 views
50

Quizás una pregunta estúpida: Tengo un List de tipo <Data> que quiero convertir en un archivo XML. Esta es mi clase Database que contiene un ArrayList ...JAXB: ¿Cómo ordenar objetos en las listas?

@XmlRootElement 
public class Database 
{ 
    List<Data> records = new ArrayList<Data>(); 

    public List<Data> getRecords()     { return records; } 
    public void  setRecords(List<Data> records) { this.records = records; } 
} 

... y esta es la clase de datos:

// @XmlRootElement 
public class Data 
{ 
    String name; 
    String address; 

    public String getName()   { return name;  } 
    public void setName(String name) { this.name = name; } 

    public String getAddress()    { return address;   } 
    public void setAddress(String address) { this.address = address; } 
} 

Usando la siguiente clase de prueba ...

public class Test 
{ 
    public static void main(String args[]) throws Exception 
    { 
     Data data1 = new Data(); 
      data1.setName("Peter"); 
      data1.setAddress("Cologne"); 

     Data data2 = new Data(); 
      data2.setName("Mary"); 
      data2.setAddress("Hamburg"); 

     Database database = new Database(); 
       database.getRecords().add(data1); 
       database.getRecords().add(data2); 

     JAXBContext context = JAXBContext.newInstance(Database.class); 
     Marshaller marshaller = context.createMarshaller(); 
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
        marshaller.marshal(database, new FileWriter("test.xml"));  
    } 
} 

. ..Tengo el resultado:

<database> 
    <records> 
     <address>Cologne</address> 
     <name>Peter</name> 
    </records> 
    <records> 
     <address>Hamburg</address> 
     <name>Mary</name> 
    </records> 
</database> 

Pero eso no es lo que esperaba, es decir, faltan todas las etiquetas para los objetos <Data>. Busco a una forma de exportar los datos en la siguiente estructura, pero no sé cómo lograr esto:

<database> 
    <records> 
     <data> 
      <address>Cologne</address> 
      <name>Peter</name> 
     </data> 
     <data> 
      <address>Hamburg</address> 
      <name>Mary</name> 
     </data> 
    </records> 
</database> 

Una cuestión adicional: si quiero tratar el problema sin usando @XmlElementWrapper y @XmlElement anotaciones, I puede introducir una clase de intermediario

public class Records 
{ 
    List<Data> data = new ArrayList<Data>(); 

    public List<Data> getData()    { return data; } 
    public void  setData(List<Data> data) { this.data = data; } 
} 

utilizado por la clase base modificada

@XmlRootElement 
public class Database 
{ 
    Records records = new Records(); 

    public Records getRecords()    { return records; } 
    public void setRecords(Records records) { this.records = records; } 
} 

en una clase ligeramente modificada Test:

... 
Database database = new Database(); 
database.getRecords().getData().add(data1); 
database.getRecords().getData().add(data2); 
... 

El resultado también es:

<database> 
    <records> 
     <data> 
      <address>Cologne</address> 
      <name>Peter</name> 
     </data> 
     <data> 
      <address>Hamburg</address> 
      <name>Mary</name> 
     </data> 
    </records> 
</database> 

es éste el recomienda manera de crear una estructura de clases de Java de acuerdo con la estructura del archivo XML anterior ?

+0

No te veo usando 'DataList' en tu clase de prueba. – joschi

+0

Disculpe, copié y pegué la clase incorrecta ... ahora se corrigió en el ejemplo anterior. – rmv

Respuesta

89

en los registros de la propiedad complemento:

@XmlElementWrapper(name="records") 
@XmlElement(name="data") 

Para obtener más información sobre las propiedades JAXB y colección ver:

+1

Genial, eso es todo! Muchas gracias. – rmv

+1

Tuve que agregar las anotaciones al "getter" para que esto funcione ... –

+2

@LawrenceTierney - El siguiente artículo sobre '@ XmlAccessorType' puede ayudar a anotar campos o propiedades (getter/setter): http: // blog. bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html –

3

Esto es en respuesta a su segunda pregunta disquised una respuesta:

Ambos enfoques generarán el mismo XML. Mi recomendación es ir con el modelo que sea mejor para su aplicación. Para mí, eso generalmente está usando @ XmlElementWrapper/@ XmlElement. Como "registros" está ahí para organizar los elementos de "datos", realmente no merece su propia clase.

que conducen a la aplicación MOXy JAXB y ofrecemos una extensión mapeo basado en XPath para ir más allá de lo que es capaz, con @XmlElementWrapper:

+0

Es bastante impresionante lo que está sucediendo en esta área. Creo que necesito algo de tiempo para ponerme en contacto con esta nueva técnica de mapeo. ¿Puede darme una primera pista, cómo leer los datos XML exportados en la estructura de clases nuevamente? Si utilizo @ XmlElementWrapper/@ XmlElement para la exportación, el programa de importación se queja de que las clases correspondientes son (obviamente :-) que no existen ... – rmv

+0

La importación (unmarshal) debería funcionar, ¿qué excepción está obteniendo? –

+1

Creo que recibí una excepción que la clase 'Registros' no se pudo encontrar. Pero para estar seguro, lo verificaré con un ejemplo mañana ... – rmv

3

En respuesta a su segunda pregunta:

Is this the recommended way to create a Java class structure 
according to the XML file structure above? 

Técnicamente hablando, la introducción de una clase extra Records para resolver su problema JAXB es un trabajo innecesario y redundante, porque JAXB no lo necesita. La propiedad @XmlElementWrapper y @XmlElementname ha sido diseñada para resolver su problema.

De sus comentarios a la respuesta de Blaise, mantengo un tutorial con ejemplos operacionales que explican cómo se manejan las clases genéricas como Lista, etc. cuando se desmarca.

+0

¡Gran sitio tutorial! – rmv

Cuestiones relacionadas