2012-09-26 20 views
5

Sto cercando di analizzare un file csv utilizzando Jackson CsvParser in un oggetto che contiene anche un elenco di un'altra classe.Java Jackson: analisi di un file csv in un oggetto contenente un elenco di oggetti

Quindi le prime 2 colonne contengono dati che devono essere associati alla classe genitore e in seguito i dati dovrebbero essere associati a un'altra classe.

public class Person { 
    private String name; 
    private String age; 
    private List<CarDetails> carDetails; 

    //Getters+setters 
} 

public class CarDetails { 
    private String carMake; 
    private String carRegistration; 

    //Getters+setters 
} 

Il log da analizzare sarà simile:

John Doe, 30, Honda, D32GHF 

O in un altro ceppo di utenti tutti con 2 auto può sembrare:

Jane Doe, 29, Mini, F64RTZ, BMW, T56DFG 

per analizzare l'iniziale 2 le voci di dati nella classe "Persona" non sono un problema.

CsvMapper mapper = new CsvMapper(); 
CsvSchema schema = CsvSchema.builder() 
    .addColumn("name") 
    .addColumn("age") 

for(numberOfCars=2; numberOfCars!=0 ; numberOfCars--) 
    schema = schema.rebuild() 
     .addColumn("carMake") 
     .addColumn("carRegistration") 

MappingIterator<Map.Entry> it = mapper 
    .reader(Person.class) 
    .with(schema) 
    .readValues(personLog); 
    List<Person> people = new ArrayList<Person>(); 
    while (it.hasNextValue()) { 
     Person person = (Person) it.nextValue(); 
     people.add(person); 
    } 

Ma non so come analizzare il CarDetails. Sembra che devo essere in grado di cercare il valore, creare un nuovo oggetto CarDetails e aggiungerlo all'oggetto Person, ma non riesco a vedere come estrarre quell'informazione.


La mia soluzione è la seguente:

List<Person> people = new ArrayList<Person>(); 

MappingIterator<Map<?,?>> it = mapper.reader(schema).withType(Map.class).readValues(personLog); 
while(it.hasNextValue()) { 
    Person person = new Person(); 
    CarDetails = new CarDetails(); 
    Map<?,?> result = it.nextValue(); 
    person.setName(result.get("name").toString()); 
    carDetails.setCarMake(result.get("carMake").toString()); 
    person.addCarDetails(carDetails); 
    people.add(person); 
}  

risposta

4

Se si guarda alla Javadoc per CsvMapper.readerWithSchemaFor, afferma:

nessun tipo CSV possono essere mappati array o collezioni

+1

Sì, sembra che non ci sia un modo pulito per farlo. Tuttavia nel frattempo ho deciso di scaricare tutto in una mappa e utilizzare lo schema per identificare le chiavi e popolare manualmente le classi. Speravo che ci fosse un modo migliore. Grazie per il tuo contributo. (Pubblicherò la mia soluzione come aggiornamento e accetto la tua risposta). – DanF7

+0

Nota che se aggiungi un serializzatore e un deserializzatore personalizzati, puoi eseguire questo tipo di conversione. A questo scopo potresti persino utilizzare l'ObjectMapper JSON standard. – StaxMan

+1

Con versioni successive (2.5 e successive), Jackson supporta in realtà semplici tipi di List/array, in cui i valori sono scalari come stringhe, enumerazioni o numeri. I separatori sono per impostazione predefinita punto e virgola (";"), ma possono essere configurati su un altro carattere. Questo purtroppo non funzionerebbe per il tuo caso dal momento che stai usando lo stesso separatore di colonne; e i tipi di valore sono anche più complessi. Ma ho pensato che valesse la pena di menzionare se altri cercassero un uso più semplice di List/array. – StaxMan

Problemi correlati