Проверка каждого файла на соответствие нескольким ограничениям с помощью синтаксического анализатора CSV.

Я работаю над требованием, когда мне нужно анализировать поля записи CSV на основе нескольких проверок. Я использую supercsv, который поддерживает процессоры полевого уровня для проверки данных.

Мое требование состоит в том, чтобы проверять каждое поле записи/строки на соответствие нескольким проверкам и сохранять их в базе данных со статусом успеха/неудачи. для записей об ошибках я должен отображать все неудачные проверки, используя некоторые коды.

Super CSV является рабочим файлом, но он проверяет только первую проверку для поля, и, если она не пройдена, игнорирует вторую проверку для того же поля. Пожалуйста, посмотрите на код ниже и помогите мне в этом.

package com.demo.supercsv;

import java.io.FileReader;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

import org.supercsv.cellprocessor.Optional;
import org.supercsv.cellprocessor.constraint.NotNull;
import org.supercsv.cellprocessor.constraint.StrMinMax;
import org.supercsv.cellprocessor.constraint.StrRegEx;
import org.supercsv.cellprocessor.constraint.UniqueHashCode;
import org.supercsv.cellprocessor.ift.CellProcessor;
import org.supercsv.exception.SuperCsvCellProcessorException;
import org.supercsv.io.CsvBeanReader;
import org.supercsv.io.CsvBeanWriter;
import org.supercsv.io.ICsvBeanReader;
import org.supercsv.io.ICsvBeanWriter;
import org.supercsv.prefs.CsvPreference;

public class ParserDemo {

    public static void main(String[] args) throws IOException {

        List<Employee> emps = readCSVToBean();
        System.out.println(emps);
        System.out.println("******");
        writeCSVData(emps);
    }

    private static void writeCSVData(List<Employee> emps) throws IOException {
        ICsvBeanWriter beanWriter = null;
        StringWriter writer = new StringWriter();
        try{
            beanWriter = new CsvBeanWriter(writer, CsvPreference.STANDARD_PREFERENCE);
            final String[] header = new String[]{"id","name","role","salary"};
            final CellProcessor[] processors = getProcessors();

            // write the header
            beanWriter.writeHeader(header);

            //write the beans data
            for(Employee emp : emps){
                beanWriter.write(emp, header, processors);
            }
        }finally{
            if( beanWriter != null ) {
                beanWriter.close();
            }
        }
        System.out.println("CSV Data\n"+writer.toString());
    }

    private static List<Employee> readCSVToBean() throws IOException {
        ICsvBeanReader beanReader = null;
        List<Employee> emps = new ArrayList<Employee>();
        try {
            beanReader = new CsvBeanReader(new FileReader("src/employees.csv"),
                    CsvPreference.STANDARD_PREFERENCE);

            // the name mapping provide the basis for bean setters 
            final String[] nameMapping = new String[]{"id","name","role","salary"};
            //just read the header, so that it don't get mapped to Employee object
            final String[] header = beanReader.getHeader(true);
            final CellProcessor[] processors = getProcessors();

            Employee emp;

            while ((emp = beanReader.read(Employee.class, nameMapping,
                    processors)) != null) {
                emps.add(emp);


                if (!CaptureExceptions.SUPPRESSED_EXCEPTIONS.isEmpty()) {
                    System.out.println("Suppressed exceptions for row "
                                        + beanReader.getRowNumber() + ":");
                    for (SuperCsvCellProcessorException e :
                        CaptureExceptions.SUPPRESSED_EXCEPTIONS) {
                        System.out.println(e);
                    }
                    // for processing next row clearing validation list
                    CaptureExceptions.SUPPRESSED_EXCEPTIONS.clear();
                }

            }

        } finally {
            if (beanReader != null) {
                beanReader.close();
            }
        }
        return emps;
    }

    private static CellProcessor[] getProcessors() {

        final CellProcessor[] processors = new CellProcessor[] { 

                new CaptureExceptions(new NotNull(new StrRegEx("\\d+",new StrMinMax(0, 2)))),//id must be in digits and should not be more than two charecters
                new CaptureExceptions(new Optional()), 
                new CaptureExceptions(new Optional()), 
                new CaptureExceptions(new NotNull()), 
                 // Salary
        };
        return processors;
    }

}

Обработчик исключений:

package com.demo.supercsv;

import java.util.ArrayList;
import java.util.List;
import org.supercsv.cellprocessor.CellProcessorAdaptor;
import org.supercsv.cellprocessor.ift.CellProcessor;
import org.supercsv.exception.SuperCsvCellProcessorException;
import org.supercsv.util.CsvContext;

public class CaptureExceptions extends CellProcessorAdaptor {

    public static List<SuperCsvCellProcessorException> SUPPRESSED_EXCEPTIONS = 
            new ArrayList<SuperCsvCellProcessorException>();

    public CaptureExceptions(CellProcessor next) {
        super(next);
    }

    public Object execute(Object value, CsvContext context) {
        try {
            return next.execute(value, context);

        } catch (SuperCsvCellProcessorException e) {
            // save the exception
            SUPPRESSED_EXCEPTIONS.add(e);
            if(value!=null)
                return value.toString();
                else
                    return "";
        }
    }
}

пример CSV-файла

ID,Name,Role,Salary
a123,kiran,CEO,"5000USD"
2,Kumar,Manager,2000USD
3,David,developer,1000USD

когда я запускаю свою программу обработчик исключений supercsv, отображающий это сообщение для значения идентификатора в первой строке

Suppressed exceptions for row 2:
org.supercsv.exception.SuperCsvConstraintViolationException: 'a123' does not match the regular expression '\d+'
processor=org.supercsv.cellprocessor.constraint.StrRegEx
context={lineNo=2, rowNo=2, columnNo=1, rowSource=[a123, kiran, CEO, 5000USD]}
[com.demo.supercsv.Employee@23bf011e, com.demo.supercsv.Employee@50e26ae7, com.demo.supercsv.Employee@40d88d2d]

длина идентификатора поля не должна быть нулевой и превышать два, и она должна быть числовой... Я определил полевой процессор следующим образом.

new CaptureExceptions(new NotNull(new StrRegEx("\\d+",new StrMinMax(0, 2))))

но супер csv игнорирует вторую проверку (максимальная длина 2), если данный ввод не является числовым... если мой ввод равен 100, то его максимальная длина проверки... но как получить две проверки для неправильного ввода. Пожалуйста, помогите мне в этом


person Kiran    schedule 20.12.2015    source источник


Ответы (1)


Процессоры ячеек SuperCSV будут работать последовательно. Таким образом, если он пройдет предыдущую проверку ограничения, он проверит следующую.

Чтобы достичь своей цели, вам нужно написать собственный CellProcessor, который будет проверять, является ли ввод числом (цифрой) и длиной от 0 до 2. Таким образом, обе эти проверки выполняются за один шаг.

person ImTiaZ    schedule 05.02.2016