字符串剪切,替换,操作案例
目录
问题:string can't convert to number
一、流程说明
三个步骤,先剪切,后替换,然后大小写转换,三个字符串的操作步骤。
二、代码
剪切
/**
* 剪切字符串
* @return
*/
private StepMeta getStringCutStep(TransMeta transMeta, PluginRegistry registry){
/**
* 1. 组装meta
*/
StringCutMeta stringCutMeta = new StringCutMeta();
/*
<fields>
<field>
<in_stream_name>title</in_stream_name>
<out_stream_name>title_begin</out_stream_name>
<cut_from>0</cut_from>
<cut_to>1</cut_to>
</field>
</fields>
*/
stringCutMeta.setFieldInStream(new String[]{"title"});
stringCutMeta.setFieldOutStream(new String[]{"title_begin"});
stringCutMeta.setCutFrom(new String[]{"0"});
stringCutMeta.setCutTo(new String[]{"1"});
/**
* 2. 添加step到交换中
*/
String stringCutPluginId = registry.getPluginId(StepPluginType.class, stringCutMeta);
StepMeta stringCutStep = new StepMeta(stringCutPluginId, "剪切字符串", (StepMetaInterface) stringCutMeta);
//设置在图形化界面中展示位置
stringCutStep.setDraw(true);
stringCutStep.setLocation(496,272);
transMeta.addStep(stringCutStep);
return stringCutStep;
}
替换
/**
* 字符串替换
* @param transMeta
* @param registry
* @return
*/
private StepMeta getReplaceStringStep(TransMeta transMeta, PluginRegistry registry){
/*
<fields>
<field>
<in_stream_name>description</in_stream_name>
<out_stream_name>desc</out_stream_name>
<use_regex>no</use_regex>
<replace_string>港剧</replace_string>
<replace_by_string>港台大片</replace_by_string>
<set_empty_string>N</set_empty_string>
<replace_field_by_string/>
<whole_word>no</whole_word>
<case_sensitive>no</case_sensitive>
<is_unicode>no</is_unicode>
</field>
</fields>
*/
ReplaceStringMeta replaceStringMeta = new ReplaceStringMeta();
replaceStringMeta.setFieldInStream(new String[]{"description"});
replaceStringMeta.setFieldOutStream(new String[]{"desc"});
replaceStringMeta.setUseRegEx(new int[]{ReplaceStringMeta.USE_REGEX_NO});//是否正则匹配,否
replaceStringMeta.setReplaceString(new String[]{"港剧"});
replaceStringMeta.setReplaceByString(new String[]{"港台大片"});
replaceStringMeta.setEmptyString(new boolean[]{false});
replaceStringMeta.setFieldReplaceByString(new String[1]);
replaceStringMeta.setWholeWord(new int[]{ReplaceStringMeta.WHOLE_WORD_NO});
replaceStringMeta.setCaseSensitive(new int[]{ReplaceStringMeta.CASE_SENSITIVE_NO});
replaceStringMeta.setIsUnicode(new int[]{ReplaceStringMeta.IS_UNICODE_NO});
String replaceStringPluginId = registry.getPluginId(StepPluginType.class, replaceStringMeta);
StepMeta replaceStringStep = new StepMeta(replaceStringPluginId, "字符串替换", (StepMetaInterface) replaceStringMeta);
replaceStringStep.setDraw(true);
replaceStringStep.setLocation(592,272);
transMeta.addStep(replaceStringStep);
return replaceStringStep;
}
操作
/**
* 字符串操作
* @param transMeta
* @param registry
* @return
*/
private StepMeta getStringOperationsStep(TransMeta transMeta, PluginRegistry registry){
StringOperationsMeta stringOperationsMeta = new StringOperationsMeta();
/*
<fields>
<field>
<in_stream_name>author</in_stream_name>
<out_stream_name>author_upper</out_stream_name>
<trim_type>both</trim_type>
<lower_upper>upper</lower_upper>
<padding_type>none</padding_type>
<pad_char/>
<pad_len/>
<init_cap>no</init_cap>
<mask_xml>none</mask_xml>
<digits>none</digits>
<remove_special_characters>none</remove_special_characters>
</field>
</fields>
*/
stringOperationsMeta.setFieldInStream(new String[]{"author"});
stringOperationsMeta.setFieldOutStream(new String[]{"author_upper"});
stringOperationsMeta.setTrimType(new int[]{ValueMetaInterface.TRIM_TYPE_BOTH});
/*
在Kettle源码高版本(9.XXX) 中,lowerUpper这个属性变成了string类型,直接使用none, upper, lower 三个属性值即可
写这个代码之前引用的是5.XXX 版本的包,但是spoon工具用的是8.XXX 版本,所以导致有点不匹配,此处换成8.2.0.0-342的包
8.2.0.0-342 这个包是我下载的源码,然后自己打包编译的,忘了是哪个版本的源码了,应该是8.2.0.0-XXX的。\
之前使用5.XXX版本的jar包,是因为5.XXX版本为了公司要求改了很多源码,对优化和支持等做了修改。
kettle后续有些meta是没有了,比如8.XXX版本中 ConcatFieldMeta这个类,就需要靠plugins中找到,要引入插件的,这应该也是后续kettle的方向,
插件式集成,方便后续扩展等。
*/
stringOperationsMeta.setLowerUpper(new int[]{StringOperationsMeta.LOWER_UPPER_UPPER});
stringOperationsMeta.setPaddingType(new int[]{StringOperationsMeta.PADDING_NONE});
stringOperationsMeta.setPadChar(new String[1]);
stringOperationsMeta.setPadLen(new String[1]);
stringOperationsMeta.setInitCap(new int[]{StringOperationsMeta.INIT_CAP_NO});
stringOperationsMeta.setMaskXML(new int[]{StringOperationsMeta.MASK_NONE});
stringOperationsMeta.setDigits(new int[]{StringOperationsMeta.DIGITS_NONE});
stringOperationsMeta.setRemoveSpecialCharacters(new int[]{StringOperationsMeta.REMOVE_SPECIAL_CHARACTERS_NONE});
String stringOperationsPluginId = registry.getPluginId(StepPluginType.class, stringOperationsMeta);
StepMeta stringOperationsStep = new StepMeta(stringOperationsPluginId, "字符串操作", (StepMetaInterface) stringOperationsMeta);
stringOperationsStep.setDraw(true);
stringOperationsStep.setLocation(720,272);
transMeta.addStep(stringOperationsStep);
return stringOperationsStep;
}
代码基本都差不多,贴出来仅供参考。
这里说一下我碰到的一个奇葩问题。
三、问题项
问题:string can't convert to number
我靠,什么鬼,以前正常的ExcelInputMeta突然不行了?检查了N遍代码,突然想起我把kettle的包从5.XXX版本升级到了8.XXX版本,或许是升级包后源码不一样了,所以需要重新设置参数。
跟踪源码后是上述图片处报错,id设置是Number,但是这个ValueMetaString是string类型,而且值竟然是id这个表头,而不是第二行的数字。
所以猜测应该是从表头开始读取的,那么也就是startRow这个ExcelInputMeta属性不管用了。
看了这个代码的调用上下文,终于在源码中发现这么一行,如果有表头,那么需要设置startsWithHeader属性去跳过,oh my god!!!
解决方式
/*
8.XXX 版本如果excel中有头部,那么需要设置,5.XXX版本不需要
*/
inputMeta.setStartsWithHeader(true);
问题、少设置属性导致空指针
解决方式:
replaceStringMeta.setFieldReplaceByString(new String[1]);
解决方式:
stringOperationsMeta.setPadChar(new String[1]);
stringOperationsMeta.setPadLen(new String[1]);
问题、节点连接错误
这个问题基本是看不出来,不报错,但是运行代码后,三四分钟都还在跑,这完全不合理。
就算我电脑渣(也不算太渣),也不可能这么长时间还运行不了一段简单的交换。
于是乎写了生成ktr文件的代码,代码如下,
private void createKtrFile(TransMeta transMeta) throws KettleException,IOException{
String xml = transMeta.getXML();
String filePath = "F:\\kette_test\\错误\\str.ktr";
BufferedWriter bw = new BufferedWriter(new FileWriter(new File(filePath)));
bw.write(xml);
bw.close();
}
将这个生成的ktr拉到spoon工具中图形化展示,展示如下,我靠,我的字符串替换节点呢?而且Excel输出和字符串操作这个连接线怎么是双向的?
检查代码后发现,replaceStringStep处的stepname使用的是Excel输出的名字,应该是拷贝代码时忘改了。
解决方式:换个独一无二的名字即可。
StepMeta replaceStringStep = new StepMeta(replaceStringPluginId, "字符串替换", (StepMetaInterface) replaceStringMeta);
四、运行
完整代码
@Before
public void before() {
try {
//初始化环境
EnvUtil.environmentInit();
KettleEnvironment.init();
} catch (KettleException e) {
log.error("", e);
}
}
@Test
public void exchangeOperStr() throws KettleException{
TransMeta transMeta = new TransMeta();
transMeta.setName("字符串剪切操作替换"); // <info> --> <name>字符串剪切操作替换</name>
PluginRegistry registry = PluginRegistry.getInstance();
StepMeta inputStep = getInputStep(transMeta,registry);
StepMeta strCutStep = getStringCutStep(transMeta,registry);
StepMeta strReplaceStep = getReplaceStringStep(transMeta,registry);
StepMeta strOperStep = getStringOperationsStep(transMeta,registry);
StepMeta outputStep = getOutputStep(transMeta,registry);
/*
4. 关联步骤
*/
transMeta.addTransHop(new TransHopMeta(inputStep, strCutStep));
transMeta.addTransHop(new TransHopMeta(strCutStep, strReplaceStep));
transMeta.addTransHop(new TransHopMeta(strReplaceStep, strOperStep));
transMeta.addTransHop(new TransHopMeta(strOperStep, outputStep));
// try {
// createKtrFile(transMeta);
// } catch (IOException e) {
// e.printStackTrace();
// }
/*
5.执行
*/
Trans trans = new Trans(transMeta);
//执行转换
trans.execute(null);
//等待完成
trans.waitUntilFinished();
if (trans.getErrors() > 0) {
System.out.println("交换出错.");
return;
}
}
/**
* 字符串替换
* @param transMeta
* @param registry
* @return
*/
private StepMeta getReplaceStringStep(TransMeta transMeta, PluginRegistry registry){
/*
<fields>
<field>
<in_stream_name>description</in_stream_name>
<out_stream_name>desc</out_stream_name>
<use_regex>no</use_regex>
<replace_string>港剧</replace_string>
<replace_by_string>港台大片</replace_by_string>
<set_empty_string>N</set_empty_string>
<replace_field_by_string/>
<whole_word>no</whole_word>
<case_sensitive>no</case_sensitive>
<is_unicode>no</is_unicode>
</field>
</fields>
*/
ReplaceStringMeta replaceStringMeta = new ReplaceStringMeta();
replaceStringMeta.setFieldInStream(new String[]{"description"});
replaceStringMeta.setFieldOutStream(new String[]{"desc"});
replaceStringMeta.setUseRegEx(new int[]{ReplaceStringMeta.USE_REGEX_NO});//是否正则匹配,否
replaceStringMeta.setReplaceString(new String[]{"港剧"});
replaceStringMeta.setReplaceByString(new String[]{"港台大片"});
replaceStringMeta.setEmptyString(new boolean[]{false});
replaceStringMeta.setFieldReplaceByString(new String[1]);
replaceStringMeta.setWholeWord(new int[]{ReplaceStringMeta.WHOLE_WORD_NO});
replaceStringMeta.setCaseSensitive(new int[]{ReplaceStringMeta.CASE_SENSITIVE_NO});
replaceStringMeta.setIsUnicode(new int[]{ReplaceStringMeta.IS_UNICODE_NO});
String replaceStringPluginId = registry.getPluginId(StepPluginType.class, replaceStringMeta);
StepMeta replaceStringStep = new StepMeta(replaceStringPluginId, "字符串替换", (StepMetaInterface) replaceStringMeta);
replaceStringStep.setDraw(true);
replaceStringStep.setLocation(592,272);
transMeta.addStep(replaceStringStep);
return replaceStringStep;
}
/**
* 字符串操作
* @param transMeta
* @param registry
* @return
*/
private StepMeta getStringOperationsStep(TransMeta transMeta, PluginRegistry registry){
StringOperationsMeta stringOperationsMeta = new StringOperationsMeta();
/*
<fields>
<field>
<in_stream_name>author</in_stream_name>
<out_stream_name>author_upper</out_stream_name>
<trim_type>both</trim_type>
<lower_upper>upper</lower_upper>
<padding_type>none</padding_type>
<pad_char/>
<pad_len/>
<init_cap>no</init_cap>
<mask_xml>none</mask_xml>
<digits>none</digits>
<remove_special_characters>none</remove_special_characters>
</field>
</fields>
*/
stringOperationsMeta.setFieldInStream(new String[]{"author"});
stringOperationsMeta.setFieldOutStream(new String[]{"author_upper"});
stringOperationsMeta.setTrimType(new int[]{ValueMetaInterface.TRIM_TYPE_BOTH});
/*
在Kettle源码高版本(9.XXX) 中,lowerUpper这个属性变成了string类型,直接使用none, upper, lower 三个属性值即可
写这个代码之前引用的是5.XXX 版本的包,但是spoon工具用的是8.XXX 版本,所以导致有点不匹配,此处换成8.2.0.0-342的包
8.2.0.0-342 这个包是我下载的源码,然后自己打包编译的,忘了是哪个版本的源码了,应该是8.2.0.0-XXX的。\
之前使用5.XXX版本的jar包,是因为5.XXX版本为了公司要求改了很多源码,对优化和支持等做了修改。
kettle后续有些meta是没有了,比如8.XXX版本中 ConcatFieldMeta这个类,就需要靠plugins中找到,要引入插件的,这应该也是后续kettle的方向,
插件式集成,方便后续扩展等。
*/
stringOperationsMeta.setLowerUpper(new int[]{StringOperationsMeta.LOWER_UPPER_UPPER});
stringOperationsMeta.setPaddingType(new int[]{StringOperationsMeta.PADDING_NONE});
stringOperationsMeta.setPadChar(new String[1]);
stringOperationsMeta.setPadLen(new String[1]);
stringOperationsMeta.setInitCap(new int[]{StringOperationsMeta.INIT_CAP_NO});
stringOperationsMeta.setMaskXML(new int[]{StringOperationsMeta.MASK_NONE});
stringOperationsMeta.setDigits(new int[]{StringOperationsMeta.DIGITS_NONE});
stringOperationsMeta.setRemoveSpecialCharacters(new int[]{StringOperationsMeta.REMOVE_SPECIAL_CHARACTERS_NONE});
String stringOperationsPluginId = registry.getPluginId(StepPluginType.class, stringOperationsMeta);
StepMeta stringOperationsStep = new StepMeta(stringOperationsPluginId, "字符串操作", (StepMetaInterface) stringOperationsMeta);
stringOperationsStep.setDraw(true);
stringOperationsStep.setLocation(720,272);
transMeta.addStep(stringOperationsStep);
return stringOperationsStep;
}
/**
* 剪切字符串
* @return
*/
private StepMeta getStringCutStep(TransMeta transMeta, PluginRegistry registry){
/**
* 1. 组装meta
*/
StringCutMeta stringCutMeta = new StringCutMeta();
/*
<fields>
<field>
<in_stream_name>title</in_stream_name>
<out_stream_name>title_begin</out_stream_name>
<cut_from>0</cut_from>
<cut_to>1</cut_to>
</field>
</fields>
*/
stringCutMeta.setFieldInStream(new String[]{"title"});
stringCutMeta.setFieldOutStream(new String[]{"title_begin"});
stringCutMeta.setCutFrom(new String[]{"0"});
stringCutMeta.setCutTo(new String[]{"1"});
/**
* 2. 添加step到交换中
*/
String stringCutPluginId = registry.getPluginId(StepPluginType.class, stringCutMeta);
StepMeta stringCutStep = new StepMeta(stringCutPluginId, "剪切字符串", (StepMetaInterface) stringCutMeta);
//设置在图形化界面中展示位置
stringCutStep.setDraw(true);
stringCutStep.setLocation(496,272);
transMeta.addStep(stringCutStep);
return stringCutStep;
}
/**
* 获取输入
*
* @return
*/
private StepMeta getInputStep(TransMeta transMeta, PluginRegistry registry) {
ExcelInputMeta inputMeta = new ExcelInputMeta(); // <type>ExcelInput</type>
//文件路径
String filePath = "F:\\kette_test\\input\\字符串剪切操作替换.xlsx";
String[] fileName = new String[]{filePath};
inputMeta.setFileName(fileName); // <name>F:\kette_test\input\字符串剪切操作替换.xlsx</name>
String[] fileMasks = new String[1];
inputMeta.setFileMask(fileMasks); // <filemask/>
String[] fileExcludeMasks = new String[1];
inputMeta.setExcludeFileMask(fileExcludeMasks); // <exclude_filemask/>
String[] filerequireds = new String[]{"N"};
inputMeta.setFileRequired(filerequireds); // <file_required>N</file_required>
String[] subFolders = new String[]{"N"};
inputMeta.setIncludeSubFolders(subFolders); // <include_subfolders>N</include_subfolders>
inputMeta.setSpreadSheetType(SpreadSheetType.POI); // <spreadsheet_type>POI</spreadsheet_type>
/*
8.XXX 版本如果excel中有头部,那么需要设置,5.XXX版本不需要
*/
inputMeta.setStartsWithHeader(true);
//第二行开始
int[] startRow = new int[]{1};
inputMeta.setStartRow(startRow);
//第一列开始
int[] startColumn = new int[]{0};
inputMeta.setStartColumn(startColumn);
//字段列
String[] fieldsName = new String[]{"id", "title", "author", "description"};
int[] fieldsType = new int[]{ValueMetaInterface.TYPE_NUMBER, ValueMetaInterface.TYPE_STRING, ValueMetaInterface.TYPE_STRING, ValueMetaInterface.TYPE_STRING};
//Excel输入 step下的 <fields> .... </fields>
ExcelInputField[] excelInputFields = new ExcelInputField[fieldsName.length];
for (int i = 0; i < excelInputFields.length; i++) {
excelInputFields[i] = new ExcelInputField();
excelInputFields[i].setName(fieldsName[i]);
excelInputFields[i].setType(fieldsType[i]);
excelInputFields[i].setTrimType(ExcelInputMeta.TYPE_TRIM_NONE);
excelInputFields[i].setRepeated(false);
}
inputMeta.setField(excelInputFields);
/**
* 2.添加步骤到交换中
*/
String inputPluginId = registry.getPluginId(StepPluginType.class, inputMeta);
StepMeta inputStep = new StepMeta(inputPluginId, "Excel输入", (StepMetaInterface) inputMeta); //<step> --> <name>Excel输入</name>
inputStep.setDraw(true);
inputStep.setLocation(384,176);
transMeta.addStep(inputStep);
return inputStep;
}
/**
* 获取输出
*
* @return
*/
private StepMeta getOutputStep(TransMeta transMeta, PluginRegistry registry) {
ExcelOutputMeta outputMeta = new ExcelOutputMeta(); // <type>ExcelOutput</type>
outputMeta.setAppend(false); // <append>N</append>
outputMeta.setHeaderEnabled(true); // <header>Y</header>
outputMeta.setFooterEnabled(false);// <footer>N</footer>
//换个名字用于区分spoon运行的输出文件
outputMeta.setFileName("F:\\kette_test\\output\\字符串剪切替换操作2"); // <name>F:\kette_test\output\字符串剪切替换操作</name>
outputMeta.setExtension("xls");// <extention>xls</extention>
outputMeta.setDoNotOpenNewFileInit(false); // <do_not_open_newfile_init>N</do_not_open_newfile_init>
outputMeta.setCreateParentFolder(false); // <create_parent_folder>N</create_parent_folder>
//字段列
String[] fieldsName = new String[]{"id", "title", "author", "description", "title_begin", "desc", "author_upper"};
int[] fieldsType = new int[]{ValueMetaInterface.TYPE_NUMBER, ValueMetaInterface.TYPE_STRING,
ValueMetaInterface.TYPE_STRING, ValueMetaInterface.TYPE_STRING, ValueMetaInterface.TYPE_STRING,
ValueMetaInterface.TYPE_STRING, ValueMetaInterface.TYPE_STRING};
// <fields> ..... </fields>
ExcelField[] excelFields = new ExcelField[fieldsName.length];
for (int i = 0; i < excelFields.length; i++) {
excelFields[i] = new ExcelField();
excelFields[i].setName(fieldsName[i]);
excelFields[i].setType(fieldsType[i]);
/*
<field>
<name>id</name>
<type>Number</type>
<format>0</format>
</field>
*/
if(fieldsName[i].equals("id")){
excelFields[i].setFormat("0"); // <format>0</format>
}
}
outputMeta.setOutputFields(excelFields);
String outPluginId = registry.getPluginId(StepPluginType.class, outputMeta);
StepMeta outputStep = new StepMeta(outPluginId, "Excel输出", (StepMetaInterface) outputMeta);// <step> --> <name>Excel输出</name>
outputStep.setDraw(true);
outputStep.setLocation(848,176);
transMeta.addStep(outputStep);
return outputStep;
}
private void createKtrFile(TransMeta transMeta) throws KettleException,IOException{
String xml = transMeta.getXML();
String filePath = "F:\\kette_test\\错误\\str.ktr";
BufferedWriter bw = new BufferedWriter(new FileWriter(new File(filePath)));
bw.write(xml);
bw.close();
}
ktr文件
<?xml version="1.0" encoding="UTF-8"?>
<transformation>
<info>
<name>字符串剪切操作替换</name>
<description/>
<extended_description/>
<trans_version/>
<trans_type>Normal</trans_type>
<directory>/</directory>
<parameters>
</parameters>
<log>
<trans-log-table>
<connection/>
<schema/>
<table/>
<size_limit_lines/>
<interval/>
<timeout_days/>
<field>
<id>ID_BATCH</id>
<enabled>Y</enabled>
<name>ID_BATCH</name>
</field>
<field>
<id>CHANNEL_ID</id>
<enabled>Y</enabled>
<name>CHANNEL_ID</name>
</field>
<field>
<id>TRANSNAME</id>
<enabled>Y</enabled>
<name>TRANSNAME</name>
</field>
<field>
<id>STATUS</id>
<enabled>Y</enabled>
<name>STATUS</name>
</field>
<field>
<id>LINES_READ</id>
<enabled>Y</enabled>
<name>LINES_READ</name>
<subject/>
</field>
<field>
<id>LINES_WRITTEN</id>
<enabled>Y</enabled>
<name>LINES_WRITTEN</name>
<subject/>
</field>
<field>
<id>LINES_UPDATED</id>
<enabled>Y</enabled>
<name>LINES_UPDATED</name>
<subject/>
</field>
<field>
<id>LINES_INPUT</id>
<enabled>Y</enabled>
<name>LINES_INPUT</name>
<subject/>
</field>
<field>
<id>LINES_OUTPUT</id>
<enabled>Y</enabled>
<name>LINES_OUTPUT</name>
<subject/>
</field>
<field>
<id>LINES_REJECTED</id>
<enabled>Y</enabled>
<name>LINES_REJECTED</name>
<subject/>
</field>
<field>
<id>ERRORS</id>
<enabled>Y</enabled>
<name>ERRORS</name>
</field>
<field>
<id>STARTDATE</id>
<enabled>Y</enabled>
<name>STARTDATE</name>
</field>
<field>
<id>ENDDATE</id>
<enabled>Y</enabled>
<name>ENDDATE</name>
</field>
<field>
<id>LOGDATE</id>
<enabled>Y</enabled>
<name>LOGDATE</name>
</field>
<field>
<id>DEPDATE</id>
<enabled>Y</enabled>
<name>DEPDATE</name>
</field>
<field>
<id>REPLAYDATE</id>
<enabled>Y</enabled>
<name>REPLAYDATE</name>
</field>
<field>
<id>LOG_FIELD</id>
<enabled>Y</enabled>
<name>LOG_FIELD</name>
</field>
<field>
<id>EXECUTING_SERVER</id>
<enabled>N</enabled>
<name>EXECUTING_SERVER</name>
</field>
<field>
<id>EXECUTING_USER</id>
<enabled>N</enabled>
<name>EXECUTING_USER</name>
</field>
<field>
<id>CLIENT</id>
<enabled>N</enabled>
<name>CLIENT</name>
</field>
</trans-log-table>
<perf-log-table>
<connection/>
<schema/>
<table/>
<interval/>
<timeout_days/>
<field>
<id>ID_BATCH</id>
<enabled>Y</enabled>
<name>ID_BATCH</name>
</field>
<field>
<id>SEQ_NR</id>
<enabled>Y</enabled>
<name>SEQ_NR</name>
</field>
<field>
<id>LOGDATE</id>
<enabled>Y</enabled>
<name>LOGDATE</name>
</field>
<field>
<id>TRANSNAME</id>
<enabled>Y</enabled>
<name>TRANSNAME</name>
</field>
<field>
<id>STEPNAME</id>
<enabled>Y</enabled>
<name>STEPNAME</name>
</field>
<field>
<id>STEP_COPY</id>
<enabled>Y</enabled>
<name>STEP_COPY</name>
</field>
<field>
<id>LINES_READ</id>
<enabled>Y</enabled>
<name>LINES_READ</name>
</field>
<field>
<id>LINES_WRITTEN</id>
<enabled>Y</enabled>
<name>LINES_WRITTEN</name>
</field>
<field>
<id>LINES_UPDATED</id>
<enabled>Y</enabled>
<name>LINES_UPDATED</name>
</field>
<field>
<id>LINES_INPUT</id>
<enabled>Y</enabled>
<name>LINES_INPUT</name>
</field>
<field>
<id>LINES_OUTPUT</id>
<enabled>Y</enabled>
<name>LINES_OUTPUT</name>
</field>
<field>
<id>LINES_REJECTED</id>
<enabled>Y</enabled>
<name>LINES_REJECTED</name>
</field>
<field>
<id>ERRORS</id>
<enabled>Y</enabled>
<name>ERRORS</name>
</field>
<field>
<id>INPUT_BUFFER_ROWS</id>
<enabled>Y</enabled>
<name>INPUT_BUFFER_ROWS</name>
</field>
<field>
<id>OUTPUT_BUFFER_ROWS</id>
<enabled>Y</enabled>
<name>OUTPUT_BUFFER_ROWS</name>
</field>
</perf-log-table>
<channel-log-table>
<connection/>
<schema/>
<table/>
<timeout_days/>
<field>
<id>ID_BATCH</id>
<enabled>Y</enabled>
<name>ID_BATCH</name>
</field>
<field>
<id>CHANNEL_ID</id>
<enabled>Y</enabled>
<name>CHANNEL_ID</name>
</field>
<field>
<id>LOG_DATE</id>
<enabled>Y</enabled>
<name>LOG_DATE</name>
</field>
<field>
<id>LOGGING_OBJECT_TYPE</id>
<enabled>Y</enabled>
<name>LOGGING_OBJECT_TYPE</name>
</field>
<field>
<id>OBJECT_NAME</id>
<enabled>Y</enabled>
<name>OBJECT_NAME</name>
</field>
<field>
<id>OBJECT_COPY</id>
<enabled>Y</enabled>
<name>OBJECT_COPY</name>
</field>
<field>
<id>REPOSITORY_DIRECTORY</id>
<enabled>Y</enabled>
<name>REPOSITORY_DIRECTORY</name>
</field>
<field>
<id>FILENAME</id>
<enabled>Y</enabled>
<name>FILENAME</name>
</field>
<field>
<id>OBJECT_ID</id>
<enabled>Y</enabled>
<name>OBJECT_ID</name>
</field>
<field>
<id>OBJECT_REVISION</id>
<enabled>Y</enabled>
<name>OBJECT_REVISION</name>
</field>
<field>
<id>PARENT_CHANNEL_ID</id>
<enabled>Y</enabled>
<name>PARENT_CHANNEL_ID</name>
</field>
<field>
<id>ROOT_CHANNEL_ID</id>
<enabled>Y</enabled>
<name>ROOT_CHANNEL_ID</name>
</field>
</channel-log-table>
<step-log-table>
<connection/>
<schema/>
<table/>
<timeout_days/>
<field>
<id>ID_BATCH</id>
<enabled>Y</enabled>
<name>ID_BATCH</name>
</field>
<field>
<id>CHANNEL_ID</id>
<enabled>Y</enabled>
<name>CHANNEL_ID</name>
</field>
<field>
<id>LOG_DATE</id>
<enabled>Y</enabled>
<name>LOG_DATE</name>
</field>
<field>
<id>TRANSNAME</id>
<enabled>Y</enabled>
<name>TRANSNAME</name>
</field>
<field>
<id>STEPNAME</id>
<enabled>Y</enabled>
<name>STEPNAME</name>
</field>
<field>
<id>STEP_COPY</id>
<enabled>Y</enabled>
<name>STEP_COPY</name>
</field>
<field>
<id>LINES_READ</id>
<enabled>Y</enabled>
<name>LINES_READ</name>
</field>
<field>
<id>LINES_WRITTEN</id>
<enabled>Y</enabled>
<name>LINES_WRITTEN</name>
</field>
<field>
<id>LINES_UPDATED</id>
<enabled>Y</enabled>
<name>LINES_UPDATED</name>
</field>
<field>
<id>LINES_INPUT</id>
<enabled>Y</enabled>
<name>LINES_INPUT</name>
</field>
<field>
<id>LINES_OUTPUT</id>
<enabled>Y</enabled>
<name>LINES_OUTPUT</name>
</field>
<field>
<id>LINES_REJECTED</id>
<enabled>Y</enabled>
<name>LINES_REJECTED</name>
</field>
<field>
<id>ERRORS</id>
<enabled>Y</enabled>
<name>ERRORS</name>
</field>
<field>
<id>LOG_FIELD</id>
<enabled>N</enabled>
<name>LOG_FIELD</name>
</field>
</step-log-table>
<metrics-log-table>
<connection/>
<schema/>
<table/>
<timeout_days/>
<field>
<id>ID_BATCH</id>
<enabled>Y</enabled>
<name>ID_BATCH</name>
</field>
<field>
<id>CHANNEL_ID</id>
<enabled>Y</enabled>
<name>CHANNEL_ID</name>
</field>
<field>
<id>LOG_DATE</id>
<enabled>Y</enabled>
<name>LOG_DATE</name>
</field>
<field>
<id>METRICS_DATE</id>
<enabled>Y</enabled>
<name>METRICS_DATE</name>
</field>
<field>
<id>METRICS_CODE</id>
<enabled>Y</enabled>
<name>METRICS_CODE</name>
</field>
<field>
<id>METRICS_DESCRIPTION</id>
<enabled>Y</enabled>
<name>METRICS_DESCRIPTION</name>
</field>
<field>
<id>METRICS_SUBJECT</id>
<enabled>Y</enabled>
<name>METRICS_SUBJECT</name>
</field>
<field>
<id>METRICS_TYPE</id>
<enabled>Y</enabled>
<name>METRICS_TYPE</name>
</field>
<field>
<id>METRICS_VALUE</id>
<enabled>Y</enabled>
<name>METRICS_VALUE</name>
</field>
</metrics-log-table>
</log>
<maxdate>
<connection/>
<table/>
<field/>
<offset>0.0</offset>
<maxdiff>0.0</maxdiff>
</maxdate>
<size_rowset>10000</size_rowset>
<sleep_time_empty>50</sleep_time_empty>
<sleep_time_full>50</sleep_time_full>
<unique_connections>N</unique_connections>
<feedback_shown>Y</feedback_shown>
<feedback_size>50000</feedback_size>
<using_thread_priorities>Y</using_thread_priorities>
<shared_objects_file/>
<capture_step_performance>N</capture_step_performance>
<step_performance_capturing_delay>1000</step_performance_capturing_delay>
<step_performance_capturing_size_limit>100</step_performance_capturing_size_limit>
<dependencies>
</dependencies>
<partitionschemas>
</partitionschemas>
<slaveservers>
</slaveservers>
<clusterschemas>
</clusterschemas>
<created_user>-</created_user>
<created_date>2021/11/16 10:48:27.770</created_date>
<modified_user>-</modified_user>
<modified_date>2021/11/16 10:48:27.770</modified_date>
<key_for_session_key/>
<is_key_private>N</is_key_private>
</info>
<notepads>
</notepads>
<order>
<hop>
<from>Excel输入</from>
<to>剪切字符串</to>
<enabled>Y</enabled>
</hop>
<hop>
<from>剪切字符串</from>
<to>字符串替换</to>
<enabled>Y</enabled>
</hop>
<hop>
<from>字符串替换</from>
<to>字符串操作</to>
<enabled>Y</enabled>
</hop>
<hop>
<from>字符串操作</from>
<to>Excel输出</to>
<enabled>Y</enabled>
</hop>
</order>
<step>
<name>Excel输入</name>
<type>ExcelInput</type>
<description/>
<distribute>Y</distribute>
<custom_distribution/>
<copies>1</copies>
<partitioning>
<method>none</method>
<schema_name/>
</partitioning>
<header>Y</header>
<noempty>Y</noempty>
<stoponempty>N</stoponempty>
<filefield/>
<sheetfield/>
<sheetrownumfield/>
<rownumfield/>
<sheetfield/>
<filefield/>
<limit>0</limit>
<encoding/>
<add_to_result_filenames>Y</add_to_result_filenames>
<accept_filenames>N</accept_filenames>
<accept_field/>
<accept_stepname/>
<file>
<name>F:\kette_test\input\字符串剪切操作替换.xlsx</name>
<filemask/>
<exclude_filemask/>
<file_required>N</file_required>
<include_subfolders>N</include_subfolders>
</file>
<fields>
<field>
<name>id</name>
<type>Number</type>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
<repeat>N</repeat>
<format/>
<currency/>
<decimal/>
<group/>
</field>
<field>
<name>title</name>
<type>String</type>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
<repeat>N</repeat>
<format/>
<currency/>
<decimal/>
<group/>
</field>
<field>
<name>author</name>
<type>String</type>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
<repeat>N</repeat>
<format/>
<currency/>
<decimal/>
<group/>
</field>
<field>
<name>description</name>
<type>String</type>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
<repeat>N</repeat>
<format/>
<currency/>
<decimal/>
<group/>
</field>
</fields>
<sheets>
</sheets>
<strict_types>N</strict_types>
<error_ignored>N</error_ignored>
<error_line_skipped>N</error_line_skipped>
<bad_line_files_destination_directory/>
<bad_line_files_extension>warning</bad_line_files_extension>
<error_line_files_destination_directory/>
<error_line_files_extension>error</error_line_files_extension>
<line_number_files_destination_directory/>
<line_number_files_extension>line</line_number_files_extension>
<shortFileFieldName/>
<pathFieldName/>
<hiddenFieldName/>
<lastModificationTimeFieldName/>
<uriNameFieldName/>
<rootUriNameFieldName/>
<extensionFieldName/>
<sizeFieldName/>
<spreadsheet_type>POI</spreadsheet_type>
<attributes/>
<cluster_schema/>
<remotesteps>
<input>
</input>
<output>
</output>
</remotesteps>
<GUI>
<xloc>384</xloc>
<yloc>176</yloc>
<draw>Y</draw>
</GUI>
</step>
<step>
<name>Excel输出</name>
<type>ExcelOutput</type>
<description/>
<distribute>Y</distribute>
<custom_distribution/>
<copies>1</copies>
<partitioning>
<method>none</method>
<schema_name/>
</partitioning>
<header>Y</header>
<footer>N</footer>
<encoding/>
<append>N</append>
<add_to_result_filenames>Y</add_to_result_filenames>
<file>
<name>F:\kette_test\output\字符串剪切替换操作</name>
<extention>xls</extention>
<do_not_open_newfile_init>N</do_not_open_newfile_init>
<create_parent_folder>N</create_parent_folder>
<split>N</split>
<add_date>N</add_date>
<add_time>N</add_time>
<SpecifyFormat>N</SpecifyFormat>
<date_time_format/>
<sheetname>Sheet1</sheetname>
<autosizecolums>N</autosizecolums>
<nullisblank>N</nullisblank>
<protect_sheet>N</protect_sheet>
<password>Encrypted </password>
<splitevery>0</splitevery>
<usetempfiles>N</usetempfiles>
<tempdirectory/>
</file>
<template>
<enabled>N</enabled>
<append>N</append>
<filename>template.xls</filename>
</template>
<fields>
<field>
<name>id</name>
<type>Number</type>
<format>0</format>
</field>
<field>
<name>title</name>
<type>String</type>
<format/>
</field>
<field>
<name>author</name>
<type>String</type>
<format/>
</field>
<field>
<name>description</name>
<type>String</type>
<format/>
</field>
<field>
<name>title_begin</name>
<type>String</type>
<format/>
</field>
<field>
<name>desc</name>
<type>String</type>
<format/>
</field>
<field>
<name>author_upper</name>
<type>String</type>
<format/>
</field>
</fields>
<custom>
<header_font_name>arial</header_font_name>
<header_font_size>10</header_font_size>
<header_font_bold>N</header_font_bold>
<header_font_italic>N</header_font_italic>
<header_font_underline>no</header_font_underline>
<header_font_orientation>horizontal</header_font_orientation>
<header_font_color>black</header_font_color>
<header_background_color>none</header_background_color>
<header_row_height>255</header_row_height>
<header_alignment>left</header_alignment>
<header_image/>
<row_font_name>arial</row_font_name>
<row_font_size>10</row_font_size>
<row_font_color>black</row_font_color>
<row_background_color>none</row_background_color>
</custom>
<attributes/>
<cluster_schema/>
<remotesteps>
<input>
</input>
<output>
</output>
</remotesteps>
<GUI>
<xloc>848</xloc>
<yloc>176</yloc>
<draw>Y</draw>
</GUI>
</step>
<step>
<name>剪切字符串</name>
<type>StringCut</type>
<description/>
<distribute>Y</distribute>
<custom_distribution/>
<copies>1</copies>
<partitioning>
<method>none</method>
<schema_name/>
</partitioning>
<fields>
<field>
<in_stream_name>title</in_stream_name>
<out_stream_name>title_begin</out_stream_name>
<cut_from>0</cut_from>
<cut_to>1</cut_to>
</field>
</fields>
<attributes/>
<cluster_schema/>
<remotesteps>
<input>
</input>
<output>
</output>
</remotesteps>
<GUI>
<xloc>496</xloc>
<yloc>272</yloc>
<draw>Y</draw>
</GUI>
</step>
<step>
<name>字符串操作</name>
<type>StringOperations</type>
<description/>
<distribute>Y</distribute>
<custom_distribution/>
<copies>1</copies>
<partitioning>
<method>none</method>
<schema_name/>
</partitioning>
<fields>
<field>
<in_stream_name>author</in_stream_name>
<out_stream_name>author_upper</out_stream_name>
<trim_type>both</trim_type>
<lower_upper>upper</lower_upper>
<padding_type>none</padding_type>
<pad_char/>
<pad_len/>
<init_cap>no</init_cap>
<mask_xml>none</mask_xml>
<digits>none</digits>
<remove_special_characters>none</remove_special_characters>
</field>
</fields>
<attributes/>
<cluster_schema/>
<remotesteps>
<input>
</input>
<output>
</output>
</remotesteps>
<GUI>
<xloc>720</xloc>
<yloc>272</yloc>
<draw>Y</draw>
</GUI>
</step>
<step>
<name>字符串替换</name>
<type>ReplaceString</type>
<description/>
<distribute>Y</distribute>
<custom_distribution/>
<copies>1</copies>
<partitioning>
<method>none</method>
<schema_name/>
</partitioning>
<fields>
<field>
<in_stream_name>description</in_stream_name>
<out_stream_name>desc</out_stream_name>
<use_regex>no</use_regex>
<replace_string>港剧</replace_string>
<replace_by_string>港台大片</replace_by_string>
<set_empty_string>N</set_empty_string>
<replace_field_by_string/>
<whole_word>no</whole_word>
<case_sensitive>no</case_sensitive>
<is_unicode>no</is_unicode>
</field>
</fields>
<attributes/>
<cluster_schema/>
<remotesteps>
<input>
</input>
<output>
</output>
</remotesteps>
<GUI>
<xloc>592</xloc>
<yloc>272</yloc>
<draw>Y</draw>
</GUI>
</step>
<step_error_handling>
</step_error_handling>
<slave-step-copy-partition-distribution>
</slave-step-copy-partition-distribution>
<slave_transformation>N</slave_transformation>
<attributes/>
</transformation>