如何将值从一列映射到多个字段?



假设我使用Open CSV,设置如下:

public class MyDto {
@CsvBindByName(column = "AFBP")
String placeholderA;
@CsvBindByNames({
@CsvBindByName(column = "ABCD"),
@CsvBindByName(column = "AFEL")
})
String placeholderB;
@CsvBindByNames({
@CsvBindByName(column = "ABCD"),
@CsvBindByName(column = "ALTM")
})
String placeholderC;
@Override
public String toString() {
return "placeholder A = " + placeholderA + ", placeholderB = " + placeholderB + ", placeholderC = " + placeholderC;
}
}

反序列化后

var csv = "AFBP,ABCDnthis is A,this is B and C";

我得到

placeholder A = this is A, placeholderB = null, placeholderC = this is B and C

而不是what I need:

placeholder A = this is A, placeholderB = this is B and C, placeholderC = this is B and C

是否有一种方法,使用这个库或类似的(提供对注释的支持),来反序列化CSV,使一列到多字段的映射成为可能?

,这是可能的,至少在OpenCSV版本5.7.1。然而,这可能会随着未来的版本而改变。

原因源于OpenCSV如何通过HeaderColumnNameMappingStrategy注册bean/Pojos字段到列映射的方式。默认情况下用于CsvToBeanBuilder:

这个构建器足够智能,可以猜测映射策略根据以下策略:

  1. 如果一个映射策略被显式设置,它总是被使用。
  2. 如果存在CsvBindByPosition或CsvCustomBindByPosition,则使用ColumnPositionMappingStrategy
  3. 否则使用HeaderColumnNameMappingStrategy。这包括使用CsvBindByNameCsvCustomBindByName的情况。的注释将被自动识别。

内部,类HeaderColumnNameMappingStrategy将调用registerBinding(..)。在这种情况下,Pojo的columnName(这里是:MyPojo)被用作fieldMap中映射信息的键。

遗憾的是,当前的实现没有检查,在第168行,如果一个键的映射已经存在(例如,ABCD)。因此,它将用placeholderC的新绑定覆盖第一个绑定字段placeholderB。因此,解析将只识别它应该将值从csv输入映射到字段placeholderC,如你所见。

侧节点:我测试了你的代码,可以确认你的问题给出的输出

我唯一想到的是:

  • 写一个你自己的头(到)列名策略的实现。
  • HeaderNameBaseMappingStrategy扩展开始。这样,您就可以正确地处理多次出现的现有字段到列映射。
  • 显然,您需要使用CsvToBeanBuilder#withMappingStrategy(..)方法注册您的自定义或多字段策略。

因此,您可以打开更改请求来支持所需的行为。这样,现有的映射策略就可以得到改进,以应对您在这里提出的问题所带来的需求。

目前,似乎没有其他选项存在。

相关内容

  • 没有找到相关文章

最新更新