2012-09-26 8 views
5

Tôi đang cố gắng phân tích tệp csv bằng cách sử dụng Jackson CsvParser thành đối tượng cũng chứa danh sách lớp khác.Java Jackson: Phân tích cú pháp tệp csv thành đối tượng chứa Danh sách đối tượng

Vì vậy, 2 cột đầu tiên chứa dữ liệu cần được ràng buộc với lớp cha và dữ liệu sau đó sẽ cần phải được ràng buộc với một lớp khác.

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 
} 

Nhật ký để được phân tích sẽ như thế nào:

John Doe, 30, Honda, D32GHF 

Hoặc trong một bản ghi của người sử dụng tất cả với 2 xe ô tô có thể trông giống như:

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

Để phân tích ban đầu 2 các mục dữ liệu cho lớp "Person" là không có vấn đề gì.

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

Nhưng tôi không biết cách phân tích cú pháp CarDetails. Có vẻ như tôi phải tìm kiếm giá trị, tạo đối tượng CarDetails mới và thêm nó vào đối tượng Person, nhưng tôi không thể xem cách trích xuất thông tin đó.


Giải pháp của tôi là như sau:

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

Trả lời

4

Nếu bạn nhìn vào Javadoc cho CsvMapper.readerWithSchemaFor, nó khẳng định:

không loại CSV có thể được ánh xạ tới mảng hoặc bộ sưu tập

+1

Có vẻ như không có cách nào rõ ràng để thực hiện việc này. Tuy nhiên trong thời gian đó tôi đã quyết định chỉ cần đổ tất cả mọi thứ vào một bản đồ và sử dụng lược đồ để xác định các khóa và cư trú các lớp bằng tay. Đã hy vọng có một cách tốt hơn. Cảm ơn vì đầu vào của bạn. (Tôi sẽ đăng giải pháp của tôi dưới dạng bản cập nhật và chấp nhận câu trả lời của bạn). – DanF7

+0

Lưu ý rằng nếu bạn thêm bộ chỉnh sửa và trình chỉnh sửa tùy chỉnh, bạn có thể thực hiện loại chuyển đổi này. Bạn thậm chí có thể sử dụng JSON 'ObjectMapper' chuẩn cho việc này. – StaxMan

+1

Với các phiên bản sau (2.5 trở lên), Jackson thực sự KHÔNG hỗ trợ các loại List/array đơn giản, trong đó giá trị là vô hướng như Strings, enums hoặc numbers. Dấu tách theo mặc định dấu chấm phẩy (";"), nhưng có thể được cấu hình để ký tự khác. Điều này sẽ không may làm việc cho trường hợp của bạn kể từ khi bạn đang sử dụng cùng một dấu phân cách như cột; và các loại giá trị phức tạp hơn. Nhưng tôi nghĩ nó đáng nói đến nếu những người khác đang tìm kiếm cách sử dụng List/array đơn giản hơn. – StaxMan