儘管這並不完全符合您的要求,但您可以通過使用具有通用功能的用戶定義Java類組件實現您的目標。用此組件的單個實例替換Get previous row fields
到Non-values in row
的步驟。在部分類 - 組件的處理器插入下面的代碼:
Object[] previousRow;
public boolean processRow(StepMetaInterface smi, StepDataInterface sdi) throws KettleException
{
// First, get a row from the default input hop
Object[] r = getRow();
// If the row object is null, we are done processing.
if (r == null) {
setOutputDone();
return false;
}
// It is always safest to call createOutputRow() to ensure that your output row's Object[] is large
// enough to handle any new fields you are creating in this step.
Object[] outputRow = createOutputRow(r, data.outputRowMeta.size());
// copy all input fields to the output fields
for (int i=0; i < getInputRowMeta().size(); i++) {
logBasic(data.inputRowMeta.getString(r, i));
if (data.inputRowMeta.getString(r, i) == null && (previousRow != null)) {
// if the current field is empty take it from the previous row
outputRow[i] = previousRow[i];
}
else {
// otherwise use the current row
outputRow[i] = r[i];
}
}
putRow(data.outputRowMeta, outputRow);
// store the current row as future previous row
previousRow = data.outputRowMeta.cloneRow(outputRow);
return true;
}
的JANINO類始終保持前一行的副本,以填補當前行的空字段。
以下測試設置演示組件的使用。在最簡單的情況下,我們處理來自一個CSV文件中讀取流:
輸入文件配置如下:
,幷包含下列數據
NUMBER;STRING;DATE;CURRENCY
1;A;01.02.2014;12,5
2;B;;13,5
;;03.12.2001;
4;;;
5;C;;
6;;20.03.2005;18,2
7;D;;
的配置用戶定義的Java類分量如下:
輸出文本文件包含增強的行 「無間隙」:
NUMBER;STRING;DATE;CURRENCY
1;A;01.02.2014; 012,50
2;B;01.02.2014; 013,50
2;B;03.12.2001; 013,50
4;B;03.12.2001; 013,50
5;C;03.12.2001; 013,50
6;C;20.03.2005; 018,20
7;D;20.03.2005; 018,20
注:
- 的成分是測試這四個數據類型,但在priciple它應該適用於所有。
- 它與實際字段數無關。
- 一旦一個字段被填充,它永遠不會被「填充」,這對您的設置來說是不錯的(我猜),但這可能不適用於其他設置。
- 該機制僅適用於字段爲
null
。只包含空格的字符串可能會破壞它,因此請確保在將所有字符串管道輸送到組件之前修剪所有字符串。
該代碼是使用http://wiki.pentaho.com/display/EAI/User+Defined+Java+Class作爲教程編寫的。
附錄
由@manu提供的鏈接包含followng代碼。它包含數字格式的特定處理。請注意,它不再是完全通用的。
Object[] previousRow;
RowMetaInterface outputMeta;
public boolean processRow(StepMetaInterface smi, StepDataInterface sdi) throws KettleException
{
// First, get a row from the default input hop
Object[] r = getRow();
// If the row object is null, we are done processing.
if (r == null) {
setOutputDone();
return false;
}
if (outputMeta == null) {
outputMeta = data.outputRowMeta.clone();
for(int i=0; i < outputMeta.size(); i++) {
ValueMetaInterface meta = outputMeta.getValueMeta(i);
if (meta.getType() == ValueMetaInterface.TYPE_NUMBER) {
meta.setPrecision(4);
meta.setConversionMask("#.####");
}
}
}
// It is always safest to call createOutputRow() to ensure that your output row's Object[] is large
// enough to handle any new fields you are creating in this step.
Object[] outputRow = createOutputRow(r, data.outputRowMeta.size());
// copy all input fields to the output fields
for (int i=0; i < getInputRowMeta().size(); i++) {
if ((r[i] == null) && (previousRow != null)) {
// if the current field is empty take it from the previous row
outputRow[i] = previousRow[i];
}
else {
// otherwise use the current row
outputRow[i] = r[i];
}
}
putRow(outputMeta, outputRow);
// store the current row as future previous row
previousRow = outputMeta.cloneRow(outputRow);
return true;
}
組件在pentaho中需要兩個輸入嗎? – 2016-07-25 04:07:44