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 读取数据之前先修复数据
- 自己解析数据,补偿引用问题
我需要处理从政府网站获取的 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 读取数据之前先修复数据
- 自己解析数据,补偿引用问题