CsvParserExamples.java
/*******************************************************************************
* Copyright 2014 Univocity Software Pty Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package com.univocity.parsers.examples;
import com.univocity.parsers.common.*;
import com.univocity.parsers.common.processor.*;
import com.univocity.parsers.common.record.*;
import com.univocity.parsers.conversions.*;
import com.univocity.parsers.csv.*;
import org.testng.annotations.*;
import java.io.*;
import java.math.*;
import java.util.*;
import java.util.Map.*;
public class CsvParserExamples extends Example {
@Test
public void example001ParseAll() throws Exception {
//##CODE_START
CsvParserSettings settings = new CsvParserSettings();
//the file used in the example uses '\n' as the line separator sequence.
//the line separator sequence is defined here to ensure systems such as MacOS and Windows
//are able to process this file correctly (MacOS uses '\r'; and Windows uses '\r\n').
settings.getFormat().setLineSeparator("\n");
// creates a CSV parser
CsvParser parser = new CsvParser(settings);
// parses all rows in one go.
List<String[]> allRows = parser.parseAll(getReader("/examples/example.csv"));
//##CODE_END
printAndValidate(null, allRows);
}
@Test
public void example002ReadSimpleCsv() throws Exception {
StringBuilder out = new StringBuilder();
CsvParserSettings settings = new CsvParserSettings();
//the file used in the example uses '\n' as the line separator sequence.
//the line separator sequence is defined here to ensure systems such as MacOS and Windows
//are able to process this file correctly (MacOS uses '\r'; and Windows uses '\r\n').
settings.getFormat().setLineSeparator("\n");
//##CODE_START
// creates a CSV parser
CsvParser parser = new CsvParser(settings);
// call beginParsing to read records one by one, iterator-style.
parser.beginParsing(getReader("/examples/example.csv"));
String[] row;
while ((row = parser.parseNext()) != null) {
println(out, Arrays.toString(row));
}
// The resources are closed automatically when the end of the input is reached,
// or when an error happens, but you can call stopParsing() at any time.
// You only need to use this if you are not parsing the entire content.
// But it doesn't hurt if you call it anyway.
parser.stopParsing();
//##CODE_END
printAndValidate(out);
}
@Test
public void example002IteratorOverCsv() throws Exception {
StringBuilder out = new StringBuilder();
CsvParserSettings settings = new CsvParserSettings();
//the file used in the example uses '\n' as the line separator sequence.
//the line separator sequence is defined here to ensure systems such as MacOS and Windows
//are able to process this file correctly (MacOS uses '\r'; and Windows uses '\r\n').
settings.getFormat().setLineSeparator("\n");
//##CODE_START
// creates a CSV parser
CsvParser parser = new CsvParser(settings);
for(String[] row : parser.iterate(getReader("/examples/example.csv"))){
println(out, Arrays.toString(row));
}
//##CODE_END
printAndValidate(out);
}
@Test
public void example002RecordIteratorOverCsv() throws Exception {
StringBuilder out = new StringBuilder();
CsvParserSettings settings = new CsvParserSettings();
//the file used in the example uses '\n' as the line separator sequence.
//the line separator sequence is defined here to ensure systems such as MacOS and Windows
//are able to process this file correctly (MacOS uses '\r'; and Windows uses '\r\n').
settings.getFormat().setLineSeparator("\n");
// creates a CSV parser
CsvParser parser = new CsvParser(settings);
//##CODE_START
for(Record record : parser.iterateRecords(getReader("/examples/example.csv"))){
println(out, Arrays.toString(record.getValues()));
}
//##CODE_END
printAndValidate(out);
}
@Test
public void example003ReadCsvWithRowProcessor() throws Exception {
//##CODE_START
// The settings object provides many configuration options
CsvParserSettings parserSettings = new CsvParserSettings();
//You can configure the parser to automatically detect what line separator sequence is in the input
parserSettings.setLineSeparatorDetectionEnabled(true);
// A RowListProcessor stores each parsed row in a List.
RowListProcessor rowProcessor = new RowListProcessor();
// You can configure the parser to use a RowProcessor to process the values of each parsed row.
// You will find more RowProcessors in the 'com.univocity.parsers.common.processor' package, but you can also create your own.
parserSettings.setProcessor(rowProcessor);
// Let's consider the first parsed row as the headers of each column in the file.
parserSettings.setHeaderExtractionEnabled(true);
// creates a parser instance with the given settings
CsvParser parser = new CsvParser(parserSettings);
// the 'parse' method will parse the file and delegate each parsed row to the RowProcessor you defined
parser.parse(getReader("/examples/example.csv"));
// get the parsed records from the RowListProcessor here.
// Note that different implementations of RowProcessor will provide different sets of functionalities.
String[] headers = rowProcessor.getHeaders();
List<String[]> rows = rowProcessor.getRows();
//##CODE_END
printAndValidate(headers, rows);
}
@Test
public void example004ReadCsvAndConvertValues() throws Exception {
final StringBuilder out = new StringBuilder();
//##CODE_START
// ObjectRowProcessor converts the parsed values and gives you the resulting row.
ObjectRowProcessor rowProcessor = new ObjectRowProcessor() {
@Override
public void rowProcessed(Object[] row, ParsingContext context) {
//here is the row. Let's just print it.
println(out, Arrays.toString(row));
}
};
// converts values in the "Price" column (index 4) to BigDecimal
rowProcessor.convertIndexes(Conversions.toBigDecimal()).set(4);
// converts the values in columns "Make, Model and Description" to lower case, and sets the value "chevy" to null.
rowProcessor.convertFields(Conversions.toLowerCase(), Conversions.toNull("chevy")).set("Make", "Model", "Description");
// converts the values at index 0 (year) to BigInteger. Nulls are converted to BigInteger.ZERO.
rowProcessor.convertFields(new BigIntegerConversion(BigInteger.ZERO, "0")).set("year");
CsvParserSettings parserSettings = new CsvParserSettings();
parserSettings.getFormat().setLineSeparator("\n");
parserSettings.setProcessor(rowProcessor);
parserSettings.setHeaderExtractionEnabled(true);
CsvParser parser = new CsvParser(parserSettings);
//the rowProcessor will be executed here.
parser.parse(getReader("/examples/example.csv"));
//##CODE_END
printAndValidate(out);
}
@Test
public void example005UsingAnnotations() throws Exception {
//##CODE_START
// BeanListProcessor converts each parsed row to an instance of a given class, then stores each instance into a list.
BeanListProcessor<TestBean> rowProcessor = new BeanListProcessor<TestBean>(TestBean.class);
CsvParserSettings parserSettings = new CsvParserSettings();
parserSettings.getFormat().setLineSeparator("\n");
parserSettings.setProcessor(rowProcessor);
parserSettings.setHeaderExtractionEnabled(true);
CsvParser parser = new CsvParser(parserSettings);
parser.parse(getReader("/examples/bean_test.csv"));
// The BeanListProcessor provides a list of objects extracted from the input.
List<TestBean> beans = rowProcessor.getBeans();
//##CODE_END
printAndValidate(beans.toString());
}
@Test
public void example006MasterDetail() throws Exception {
//##CODE_START
// 1st, Create a RowProcessor to process all "detail" elements
ObjectRowListProcessor detailProcessor = new ObjectRowListProcessor();
// converts values at in the "Amount" column (position 1 in the file) to integer.
detailProcessor.convertIndexes(Conversions.toInteger()).set(1);
// 2nd, Create MasterDetailProcessor to identify whether or not a row is the master row.
// the row placement argument indicates whether the master detail row occurs before or after a sequence of "detail" rows.
MasterDetailListProcessor masterRowProcessor = new MasterDetailListProcessor(RowPlacement.BOTTOM, detailProcessor) {
@Override
protected boolean isMasterRecord(String[] row, ParsingContext context) {
//Returns true if the parsed row is the master row.
//In this example, rows that have "Total" in the first column are master rows.
return "Total".equals(row[0]);
}
};
// We want our master rows to store BigIntegers in the "Amount" column
masterRowProcessor.convertIndexes(Conversions.toBigInteger()).set(1);
CsvParserSettings parserSettings = new CsvParserSettings();
parserSettings.setHeaderExtractionEnabled(true);
// Set the RowProcessor to the masterRowProcessor.
parserSettings.setProcessor(masterRowProcessor);
parserSettings.getFormat().setLineSeparator("\n");
CsvParser parser = new CsvParser(parserSettings);
parser.parse(getReader("/examples/master_detail.csv"));
// Here we get the MasterDetailRecord elements.
List<MasterDetailRecord> rows = masterRowProcessor.getRecords();
MasterDetailRecord masterRecord = rows.get(0);
// The master record has one master row and multiple detail rows.
Object[] masterRow = masterRecord.getMasterRow();
List<Object[]> detailRows = masterRecord.getDetailRows();
//##CODE_END
printAndValidate(masterRow, detailRows);
}
@Test
public void example007Columns() throws Exception {
//##CODE_START
CsvParserSettings parserSettings = new CsvParserSettings();
parserSettings.getFormat().setLineSeparator("\n");
parserSettings.setHeaderExtractionEnabled(true);
// To get the values of all columns, use a column processor
ColumnProcessor rowProcessor = new ColumnProcessor();
parserSettings.setProcessor(rowProcessor);
CsvParser parser = new CsvParser(parserSettings);
//This will kick in our column processor
parser.parse(getReader("/examples/example.csv"));
//Finally, we can get the column values:
Map<String, List<String>> columnValues = new TreeMap<String, List<String>>(rowProcessor.getColumnValuesAsMapOfNames());
//##CODE_END
StringBuilder out = new StringBuilder();
for (Entry<String, List<String>> e : columnValues.entrySet()) {
List<String> values = e.getValue();
String columnName = e.getKey();
println(out, columnName + " -> " + values);
}
printAndValidate(out);
}
@Test
public void example008CustomConversionAnnotation() throws Exception {
StringBuilder out = new StringBuilder();
CsvParserSettings parserSettings = new CsvParserSettings();
parserSettings.getFormat().setLineSeparator("\n");
parserSettings.setHeaderExtractionEnabled(true);
//##CODE_START
BeanListProcessor<Car> rowProcessor = new BeanListProcessor<Car>(Car.class);
parserSettings.setProcessor(rowProcessor);
CsvParser parser = new CsvParser(parserSettings);
parser.parse(getReader("/examples/example.csv"));
//Let's get our cars
List<Car> cars = rowProcessor.getBeans();
for (Car car : cars) {
// Let's get only those cars that actually have some description
if (!car.getDescription().isEmpty()) {
println(out, car.getDescription() + " - " + car.toString());
}
}
//##CODE_END
printAndValidate(out);
}
@Test
public void example009ParallelProcessing() throws Exception {
StringBuilder out = new StringBuilder();
CsvParserSettings parserSettings = new CsvParserSettings();
parserSettings.getFormat().setLineSeparator("\n");
parserSettings.setHeaderExtractionEnabled(true);
BeanListProcessor<Car> rowProcessor = new BeanListProcessor<Car>(Car.class);
//##CODE_START
parserSettings.setProcessor(new ConcurrentRowProcessor(rowProcessor));
//##CODE_END
CsvParser parser = new CsvParser(parserSettings);
parser.parse(getReader("/examples/example.csv"));
//Let's get our cars
List<Car> cars = rowProcessor.getBeans();
for (Car car : cars) {
// Let's get only those cars that actually have some description
if (!car.getDescription().isEmpty()) {
println(out, car.getDescription() + " - " + car.toString());
}
}
printAndValidate(out);
}
@Test
public void example010Escaping() throws Exception {
StringBuilder out = new StringBuilder();
CsvParserSettings settings = new CsvParserSettings();
//##CODE_START
// quotes inside quoted values are escaped as \"
settings.getFormat().setQuoteEscape('\\');
// but if two backslashes are found before a quote symbol they represent a single slash.
settings.getFormat().setCharToEscapeQuoteEscaping('\\');
//##CODE_END
CsvParser parser = new CsvParser(settings);
List<String[]> allRows = parser.parseAll(new InputStreamReader(getClass().getResourceAsStream("/examples/escape.csv"), "UTF-8"));
for (String[] row : allRows) {
for (String col : row) {
print(out, "[" + col + "]\t");
}
println(out);
}
printAndValidate(out);
}
@Test
public void example011ErrorHandling() throws Exception {
final StringBuilder out = new StringBuilder();
CsvParserSettings settings = new CsvParserSettings();
settings.getFormat().setLineSeparator("\n");
//##CODE_START
BeanListProcessor<AnotherTestBean> beanProcessor = new BeanListProcessor<AnotherTestBean>(AnotherTestBean.class);
settings.setProcessor(beanProcessor);
//Let's set a RowProcessorErrorHandler to log the error. The parser will keep running.
settings.setProcessorErrorHandler(new RowProcessorErrorHandler() {
@Override
public void handleError(DataProcessingException error, Object[] inputRow, ParsingContext context) {
println(out, "Error processing row: " + Arrays.toString(inputRow));
println(out, "Error details: column '" + error.getColumnName() + "' (index " + error.getColumnIndex() + ") has value '" + inputRow[error.getColumnIndex()] + "'");
}
});
CsvParser parser = new CsvParser(settings);
parser.parse(getReader("/examples/bean_test.csv"));
println(out);
println(out, "Printing beans that could be parsed");
println(out);
for (AnotherTestBean bean : beanProcessor.getBeans()) {
println(out, bean); //should print just one bean here
}
//##CODE_END
printAndValidate(out);
}
@Test
public void example011ErrorHandlingWithRetry() {
final StringBuilder out = new StringBuilder();
CsvParserSettings settings = new CsvParserSettings();
settings.getFormat().setLineSeparator("\n");
BeanListProcessor<AnotherTestBean> beanProcessor = new BeanListProcessor<AnotherTestBean>(AnotherTestBean.class);
settings.setProcessor(beanProcessor);
//##CODE_START
settings.setProcessorErrorHandler(new RetryableErrorHandler<ParsingContext>() {
@Override
public void handleError(DataProcessingException error, Object[] inputRow, ParsingContext context) {
println(out, "Error processing row: " + Arrays.toString(inputRow));
println(out, "Error details: column '" + error.getColumnName() + "' (index " + error.getColumnIndex() + ") has value '" + inputRow[error.getColumnIndex()] + "'. Setting it to null");
if(error.getColumnIndex() == 0){
setDefaultValue(null);
} else {
keepRecord(); //prevents the parser from discarding the row.
}
}
});
//##CODE_END
CsvParser parser = new CsvParser(settings);
parser.parse(getReader("/examples/bean_test.csv"));
println(out);
println(out, "Printing beans that could be parsed");
println(out);
for (AnotherTestBean bean : beanProcessor.getBeans()) {
println(out, bean); //should print two beans
}
printAndValidate(out);
}
@Test
public void example012FormatAutodetection() throws Exception {
CsvParserSettings settings = new CsvParserSettings();
//##CODE_START
//turns on automatic detection of line separators, column separators, quotes & quote escapes
settings.detectFormatAutomatically();
CsvParser parser = new CsvParser(settings);
List<String[]> rows;
//First, CSV we've been using to demonstrate all examples.
println("Data in /examples/example.csv:");
rows = parser.parseAll(getReader("/examples/example.csv"));
printRows(rows, false);
//Then, the same data but in European style (column separator is ; and decimals are separated by ,). We also escaped quotes with \ instead of using double quotes
println("\nData in /examples/european.csv:");
rows = parser.parseAll(getReader("/examples/european.csv"));
printRows(rows, false);
//Let's see the detected format:
println("\nFormat detected in /examples/european.csv:");
CsvFormat detectedFormat = parser.getDetectedFormat();
println(detectedFormat);
//##CODE_END
printAndValidate();
}
@Test
public void example013ParseKeepingEscapeSequences() throws Exception {
CsvParserSettings settings = new CsvParserSettings();
settings.setHeaderExtractionEnabled(true);
//let's parse the file seen in the previous example, where quotes are escaped using \
settings.detectFormatAutomatically();
//##CODE_START
//now we want to keep the escape sequences. We should see the slash before the quotes.
settings.setKeepEscapeSequences(true);
CsvParser parser = new CsvParser(settings);
List<String[]> allRows = parser.parseAll(getReader("/examples/european.csv"));
//##CODE_END
printAndValidate(null, allRows);
}
@Test
public void example014ParseMultipleBeansInSingleRow() {
CsvParserSettings settings = new CsvParserSettings();
settings.getFormat().setLineSeparator("\n");
//##CODE_START
// The MultiBeanProcessor allows multiple bean instances to be created from a single input record.
// in this example, we will create instances of TestBean and AnotherTestBean.
// Here we use a MultiBeanListProcessor which is a convenience class that implements the
// abstract beanProcessed() method of MultiBeanProcessor to add each instance to a list.;
MultiBeanListProcessor processor = new MultiBeanListProcessor(TestBean.class, AnotherTestBean.class);
// one of the records in the input won't be compatible with AnotherTestBean: the field "pending"
// only accepts 'y' or 'n' as valid representations of true or false. We want to continue processing, let's ignore the error.
settings.setProcessorErrorHandler(new RowProcessorErrorHandler() {
@Override
public void handleError(DataProcessingException error, Object[] inputRow, ParsingContext context) {
//ignore the error.
}
});
// we also need to grab the headers from our input file
settings.setHeaderExtractionEnabled(true);
//let's configure the parser to use our MultiBeanProcessor
settings.setProcessor(processor);
CsvParser parser = new CsvParser(settings);
//and parse everything.
parser.parse(getReader("/examples/bean_test.csv"));
// we can get all beans parsed from the input as a map, where the keys are the bean type associated
// with a list of corresponding bean instances
Map<Class<?>, List<?>> beans = processor.getBeans();
// or we can get the lists of beans processed individually by providing the type:
List<TestBean> testBeans = processor.getBeans(TestBean.class);
List<AnotherTestBean> anotherTestBeans = processor.getBeans(AnotherTestBean.class);
//Let's have a look:
println("TestBeans\n----------------");
for (TestBean testBean : testBeans) {
println(testBean);
}
//We expect one of the instances here to be null
println("\nAnotherTestBeans\n----------------");
for (AnotherTestBean anotherTestBean : anotherTestBeans) {
println(anotherTestBean);
}
//##CODE_END
printAndValidate();
}
@Test
public void example015QuoteAndEscapeHandling() {
CsvParserSettings settings = new CsvParserSettings();
//##CODE_START
settings.setUnescapedQuoteHandling(UnescapedQuoteHandling.STOP_AT_CLOSING_QUOTE);
settings.getFormat().setLineSeparator("\r\n");
//let's quote values with single quotes
settings.getFormat().setQuote('\'');
settings.getFormat().setQuoteEscape('\'');
//Line separators are normalized by default. This means they are all converted to \n, including line separators found within quoted values.
parse("value 1,'line 1\r\nline 2',value 3", settings, "Normalizing line endings");
//result: [value 1, line 1\nline 2, value 3]
//You can disable this behavior to keep the original line separators in parsed values.
settings.setNormalizeLineEndingsWithinQuotes(false);
parse("value 1,'line 1\r\nline 2',value 3", settings, "Without normalized line endings");
//result: [value 1, line 1\r\nline 2, value 3]
//Values that contain a quote character, but are not enclosed within quotes, are read as-is
parse("value 1,I'm NOT a quoted value,value 3", settings, "Value with a quote, not enclosed");
//result: [value 1, I'm NOT a quoted value, value 3]
//But if your input comes with escaped quotes, and is not enclosed within quotes you'll get the escape sequence
parse("value 1,I''m NOT a quoted value,value 3", settings, "Value with quote, escaped, not enclosed");
//result: [value 1, I''m NOT a quoted value, value 3]
//Turn on the escape unquoted values to correctly unescape this sort of input
settings.setEscapeUnquotedValues(true);
parse("value 1,I''m NOT a quoted value,value 3", settings, "Value with quote, escaped, not enclosed, processing escape");
//result: [value 1, I'm NOT a quoted value, value 3]
//As usual, when you parse values that have escaped characters, such as the quote, you get the unescaped result.
parse("value 1,'I''m a quoted value',value 3", settings, "Enclosed value, quote escaped");
//result: [value 1, I'm a quoted value, value 3]
//But in some cases you might want to get the original text, character by character, including the original escape sequence
settings.setKeepEscapeSequences(true);
parse("value 1,'I''m a quoted value',value 3", settings, "Enclosed value, quote escaped, keeping escape sequences");
//result: [value 1, I''m a quoted value, value 3]
//By default, the parser handles broken quote escapes, so it won't complain about "I'm" not being escaped properly (should be "I''m").
parse("value 1,'I'm a broken quoted value',value 3", settings, "Enclosed value, broken quote escape");
//result: [value 1, I'm a broken quoted value, value 3]
//But you can disable this and get exceptions instead.
settings.setUnescapedQuoteHandling(UnescapedQuoteHandling.RAISE_ERROR);
try {
parse("value 1,'Hey, I'm a broken quoted value',value 3", settings, "This will blow up");
} catch (TextParsingException exception) {
//The exception will give you better details about what went wrong, and where.
println("Quote escape error. Parser stopped after reading: [" + exception.getParsedContent() + "] of column " + exception.getColumnIndex());
}
//##CODE_END
printAndValidate();
}
@Test
public void example016ParseReadingComments() {
CsvParserSettings settings = new CsvParserSettings();
settings.getFormat().setLineSeparator("\n");
//##CODE_START
// This configures the parser to store all comments found in the input.
// You'll be able to retrieve the last parsed comment or all comments parsed at
// any given time during the parsing.
settings.setCommentCollectionEnabled(true);
CsvParser parser = new CsvParser(settings);
parser.beginParsing(getReader("/examples/example.csv"));
String[] row;
while ((row = parser.parseNext()) != null) {
// using the getContext method we have access to the parsing context, from where the comments found so far can be accessed
// let's get the last parsed comment and print it out in front of each parsed row.
String comment = parser.getContext().lastComment();
if (comment == null || comment.trim().isEmpty()) {
comment = "No relevant comments yet";
}
println("Comment: " + comment + ". Parsed: " + Arrays.toString(row));
}
// We can also get all comments parsed.
println("\nAll comments found:\n-------------------");
//The comments() method returns a map of line numbers associated with the comments found in them.
Map<Long, String> comments = parser.getContext().comments();
for (Entry<Long, String> e : comments.entrySet()) {
long line = e.getKey();
String commentAtLine = e.getValue();
println("Line: " + line + ": '" + commentAtLine + "'");
}
//##CODE_END
printAndValidate();
}
@Test
public void example017ParseMultiSchema() {
//##CODE_START
//Here's a master-detail schema, with rows using different formats. Rows starting with MASTER are master rows
//and they are followed by one or more car records.
StringReader input = new StringReader("" +
"MASTER,Value 1,Value 2\n" +
"2012,Toyota,Camry,10000\n" +
"2014,Toyota,Camry,12000\n" +
"MASTER,Value 3\n" +
"1982,Volkswagen,Beetle,3500"
);
//We are going to collect all MASTER records using a processor for lists of Object[]
final ObjectRowListProcessor masterElementProcessor = new ObjectRowListProcessor();
//And rows with car information will be parsed into a list of Car objects.
final BeanListProcessor<Car> carProcessor = new BeanListProcessor(Car.class);
//We create a switch based on the first column of the input. Values of each column of each row
//will be compared against registered processors that "know" how to parse the input row.
InputValueSwitch inputSwitch = new InputValueSwitch(0) {
// the input value switch allows you to override the "rowProcessorSwitched" so you can handle
// what should happen when a different type of row is found in the input.
public void rowProcessorSwitched(RowProcessor from, RowProcessor to) {
//let's add associate the list of parsed Car instances to the MASTER record parsed before.
//when the current row processor is not the "carProcessor" anymore, it means we parsed all cars under a MASTER record
if (from == carProcessor) {
List<Object[]> masterRows = masterElementProcessor.getRows();
int lastMasterRowIndex = masterRows.size() - 1;
Object[] lastMasterRow = masterRows.get(lastMasterRowIndex);
//let's expand the last master row
Object[] masterRowWithCars = Arrays.copyOf(lastMasterRow, 3);
//and add our parsed car list in the last element:
masterRowWithCars[2] = new ArrayList<Car>(carProcessor.getBeans());
masterRows.set(lastMasterRowIndex, masterRowWithCars);
//clear the list of cars so it's empty for the next batch of cars under another master row.
carProcessor.getBeans().clear();
}
}
};
//Rows whose value at column 0 is "MASTER" will be processed using the masterElementProcessor.
inputSwitch.addSwitchForValue("MASTER", masterElementProcessor, 1, 2); //we are not interested in the "MASTER" value at column 0, let's select which columns to get values from
//Car records don't have an identifier in their rows. In this case the input switch will use a "default" processor
//to handle the input. All records that don't start with "SUPER" are Car records, we use the car processor as the default.
inputSwitch.setDefaultSwitch(carProcessor, "year", "make", "model", "price"); //the header list here matches the fields annotated in the Car class.
//All we need now is to set row processor of our parser, which is the input switch.
CsvParserSettings settings = new CsvParserSettings();
settings.setProcessor(inputSwitch);
settings.getFormat().setLineSeparator("\n");
//and parse!
CsvParser parser = new CsvParser(settings);
parser.parse(input);
//Let's have a look at our master rows which contain lists of cars:
List<Object[]> rows = masterElementProcessor.getRows();
for (Object[] row : rows) {
println(Arrays.toString(row));
}
//##CODE_END
printAndValidate();
}
@Test
public void example018ParseAllRecords() throws Exception {
CsvParserSettings settings = new CsvParserSettings();
//the file used in the example uses '\n' as the line separator sequence.
//the line separator sequence is defined here to ensure systems such as MacOS and Windows
//are able to process this file correctly (MacOS uses '\r'; and Windows uses '\r\n').
settings.getFormat().setLineSeparator("\n");
//##CODE_START
// configure to grab headers from file. We want to use these names to get values from each record.
settings.setHeaderExtractionEnabled(true);
// creates a CSV parser
CsvParser parser = new CsvParser(settings);
// parses all records in one go.
List<Record> allRecords = parser.parseAllRecords(getReader("/examples/example.csv"));
for(Record record : allRecords){
print("Year: " + record.getValue("year", 2000)); //defaults year to 2000 if value is null.
print(", Model: " + record.getString("model"));
println(", Price: " + record.getBigDecimal("price"));
}
//##CODE_END
printAndValidate();
}
@Test
public void example019IterateOverRecords() throws Exception {
CsvParserSettings settings = new CsvParserSettings();
//the file used in the example uses '\n' as the line separator sequence.
//the line separator sequence is defined here to ensure systems such as MacOS and Windows
//are able to process this file correctly (MacOS uses '\r'; and Windows uses '\r\n').
settings.getFormat().setLineSeparator("\n");
// configure to grab headers from file. We want to use these names to get values from each record.
settings.setHeaderExtractionEnabled(true);
// creates a CSV parser
CsvParser parser = new CsvParser(settings);
//##CODE_START
// call beginParsing to read records one by one, iterator-style.
parser.beginParsing(getReader("/examples/example.csv"));
//among many other things, we can set default values of one ore more columns in the record metadata.
//Let's again set year to 2000 if it comes as null.
parser.getRecordMetadata().setDefaultValueOfColumns(2000, "year");
Record record;
while ((record = parser.parseNextRecord()) != null) {
print("Year: " + record.getInt("year"));
print(", Model: " + record.getString("model"));
println(", Price: " + record.getBigDecimal("price"));
}
//##CODE_END
// The resources are closed automatically when the end of the input is reached,
// or when an error happens, but you can call stopParsing() at any time.
// You only need to use this if you are not parsing the entire content.
// But it doesn't hurt if you call it anyway.
parser.stopParsing();
printAndValidate();
}
private void parse(String input, CsvParserSettings settings, String message) {
String[] values = null;
values = new CsvParser(settings).parseLine(input);
values = displayLineSeparators(values);
println("\n" + message + ":\n\t" + Arrays.toString(values));
}
private void printRows(List<String[]> rows, boolean expand) {
println("Printing " + rows.size() + " rows");
int rowCount = 0;
for (String[] row : rows) {
println("Row " + ++rowCount + " (length " + row.length + "): " + Arrays.toString(row));
if (expand) {
int valueCount = 0;
for (String value : row) {
println("\tvalue " + ++valueCount + ": " + value);
}
}
}
}
}