【问题标题】:Univocity - parse each TSV file row to different Type of class objectUnivocity - 将每个 TSV 文件行解析为不同类型的类对象
【发布时间】:2016-07-15 05:42:20
【问题描述】:

我有一个 tsv 文件,它有固定的行,但每一行都映射到不同的 Java 类。

例如。

recordType  recordValue1
recordType  recordValue1 recordValue2

对于第一行,我有以下课程:

public class FirstRow implements ItsvRecord {

    @Parsed(index = 0)
    private String recordType;

    @Parsed(index = 1)
    private String recordValue1;

    public FirstRow() {
    }
}

第二行我有:

public class SecondRow implements ItsvRecord {

    @Parsed(index = 0)
    private String recordType;

    @Parsed(index = 1)
    private String recordValue1;

    public SecondRow() {
    }
}

我想将 TSV 文件直接解析为相应的对象,但我没有想法。

【问题讨论】:

    标签: univocity


    【解决方案1】:

    使用InputValueSwitch。这将匹配每一行的特定列中的值,以确定要使用的RowProcessor。示例:

    为您需要处理的每种类型的记录创建两个(或更多)处理器:

    final BeanListProcessor<FirstRow> firstProcessor = new BeanListProcessor<FirstRow>(FirstRow.class);
    final BeanListProcessor<SecondRow> secondProcessor = new BeanListProcessor<SecondRow>(SecondRow.class);
    

    创建一个InputValueSwitch:

    //0 means that the first column of each row has a value that 
    //identifies what is the type of record you are dealing with
    InputValueSwitch valueSwitch = new InputValueSwitch(0);
    
    //assigns the first processor to rows whose first column contain the 'firstRowType' value
    valueSwitch.addSwitchForValue("firstRowType", firstProcessor);
    
    //assigns the second processor to rows whose first column contain the 'secondRowType' value
    valueSwitch.addSwitchForValue("secondRowType", secondProcessor);
    

    照常解析:

    TsvParserSettings settings = new TsvParserSettings(); //configure...
    // your row processor is the switch
    settings.setProcessor(valueSwitch);
    
    TsvParser parser = new TsvParser(settings);
    
    Reader input = new StringReader(""+
            "firstRowType\trecordValue1\n" +
            "secondRowType\trecordValue1\trecordValue2");
    
    parser.parse(input);
    

    从你的处理器中获取解析的对象:

    List<FirstRow> firstTypeObjects = firstProcessor.getBeans();
    List<SecondRow> secondTypeObjects = secondProcessor.getBeans();
    

    输出将是*:

    [FirstRow{recordType='firstRowType', recordValue1='recordValue1'}]
    
    [SecondRow{recordType='secondRowType', recordValue1='recordValue1', recordValue2='recordValue2'}]
    
    • 假设您在类中实现了一个健全的 toString()

    如果你想管理被解析对象之间的关联:

    如果您的FirstRow 应该包含为SecondRow 类型的记录解析的元素,只需覆盖rowProcessorSwitched 方法:

        InputValueSwitch valueSwitch = new InputValueSwitch(0) {
        @Override
        public void rowProcessorSwitched(RowProcessor from, RowProcessor to) {
            if (from == secondProcessor) {
                List<FirstRow> firstRows = firstProcessor.getBeans();
                FirstRow mostRecentRow = firstRows.get(firstRows.size() - 1);
    
                mostRecentRow.addRowsOfOtherType(secondProcessor.getBeans());
                secondProcessor.getBeans().clear();
            }
        }
    };
    
    • 以上假设您的FirstRow 类有一个addRowsOfOtherType 方法,该方法将SecondRow 列表作为参数。

    就是这样!

    您甚至可以混合搭配其他类型的RowProcessor。还有另一个例子here 证明了这一点。

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多