Camel CsvDataFormat 解组 Excel csv 文件的多个问题

Camel CsvDataFormat unmarshal multiple issues with Excel csv files

我需要处理从政府网站获取的 csv 文件。该文件有两个不同的格式问题,Camel CsvDataFormat unmarshal 无法同时处理这些问题。最小测试文件:

Registration No,Trade Name
"A009928","Rotagen "Combo""
"A010343","Vet Direct Abamectin Wormer, Bot + Tape"

使用此代码解组:

CsvDataFormat csv = new CsvDataFormat();
csv.setDelimiter(","); 
csv.setQuoteDisabled(true); 
csv.setUseMaps(false);
from("file://c:/temp?fileName=test.csv&noop=true")
           .unmarshal(csv)
           .process(new Processor() {
                public void process(Exchange exchange) throws Exception {
                     List<List<String>> rows = (List<List<String>>) exchange.getIn().getBody();
                     for (int j = 0; j< rows.size();j++) {
                        List<String> row = rows.get(j);
    
                        for (int i = 0; i< row.size();i++) {
                            log.info("ITEM["+row.get(i)+"]");
                            }
                     
                        
                     }
               }
           
        });


当 setQuoteDisabled(false) 我得到:

java.lang.IllegalStateException: IOException reading next record: java.io.IOException: (line 2) invalid char between encapsulated token and delimiter

当 setQuoteDisabled(true) 时,文件未编组但第 3 行在额外的 ',' 处结束了额外的拆分 这是输出:

13:10| INFO | MainRoute.java 54 | ITEM[Registration No]
13:10| INFO | MainRoute.java 54 | ITEM[Trade Name]
13:10| INFO | MainRoute.java 54 | ITEM["A009928"]
13:10| INFO | MainRoute.java 54 | ITEM["Rotagen "Combo""]
13:10| INFO | MainRoute.java 54 | ITEM["A010343"]
13:10| INFO | MainRoute.java 54 | ITEM["Vet Direct Abamectin Wormer]
13:10| INFO | MainRoute.java 54 | ITEM[ Bot + Tape"]

如何配置 CsvDataFormat 以正确解组两行?

.csv 文件的第二行违反了 csv 中的引用规则,或者至少是 commons-csv 的默认选项所理解的(camel 库在幕后使用这些类型的东西)。

处理引号内引号的默认方式是通过重复两次来转义内引号。保留 setQuoteDisabled(false) 并将 .csv-file 中的第二行更正为:

"A009928","Rotagen ""Combo"""

嗯,这是CSV作为“软标准”的问题。行和分隔符或多或少是标准化的,但是当涉及到引号时,它就变得复杂了。

由于你的数据被引用(即每个字段值都在引号中),正确的配置是

setQuoteDisabled(false)

第二条记录适用于此配置。

"A010343","Vet Direct Abamectin Wormer, Bot + Tape"

因为字段是用引号括起来的,数据里面的逗号是没有问题的。

但是,第一条记录在数据中包含 引号

"A009928","Rotagen "Combo""

根据 RFC-4180,第 2.7 段 此类引号必须转义并附加引号

If double-quotes are used to enclose fields, then a double-quote appearing inside a field must be escaped by preceding it with another double quote.

"A009928","Rotagen ""Combo"""

您可以尝试在一条记录中手动修复此问题,看看它是否像这样工作。

通常,您有多种选择:

  • 通知数据提供者他的数据不符合 RFC-4180 并要求他修复
  • 在使用 Camel 读取数据之前先修复数据
  • 自己解析数据,补偿引用问题