Rdf-File根據協議布局模板和數據定義模板,來進行文件的解析與生成。通過協議布局和數據定義模板,能夠明確計算出頭尾占用的行數,這樣可以更精確的分離出head,body,tail。
目前組件實現的協議布局模板可以分為如下兩大類:
-
開放式基金業務數據交換協議 這種國家標準文件, 數據是以補位后定長形式展示的。 存在缺點有:
-
文件雖然是文本格式,但是內容肉眼無法看懂。
-
定長補位導致文件存儲浪費。
-
因為是國家標準,文件內容定義十分全面,但是實際標準定義了六七十個字段, 有用的就十來個, 沒用的字段也需要占用存儲空間。
-
字段通過分隔符分割, 字段內容由交互雙方約定。優點是用多少就占用多少,缺點是各方文件格式、內容差異可能比較大。
一:SP
SP是簡單格式simple的意思。
sp協議布局模板
<protocol name="sp"><head><row><column><output>${column.value()}</output></column></row></head><body><row><column><output>${column.value()}</output></column></row></body><tail><row><column><output>${column.value()}</output></column></row></tail>
</protocol>
- 文件布局分為head, body, tail 三部分。
- head, body, tail字段都是橫向輸出,根據分隔符連接而成。
- head,tail 都只有一行。
sp 數據定義模板示例
{"head": ["totalCount|總筆數|Required|Integer","totalAmount|總金額|BigDecimal|Required"],"body": ["seq|流水號","instSeq|基金公司訂單號|Required","gmtApply|訂單申請時間|Date:yyyy-MM-dd HH:mm:ss","date|普通日期|Date:yyyyMMdd","dateTime|普通日期時間|Date:yyyyMMdd HH:mm:ss","applyNumber|普通數字|BigDecimal","amount|金額|BigDecimal","age|年齡|Integer","longN|長整型|Long","bol|布爾值|Boolean","memo|備注"],"tail": ["fileEnd|數據文件尾部字符|default:OFDCFEND"],"protocol": "SP"
}
SP文件示例
100|300.03
seq_0|inst_seq_0|2013-11-09 12:34:56|20131109|20131112 12:23:34|23.33|10.22|22|12345|true|備注1
seq_1|inst_seq_1|2013-11-10 15:56:12|20131110|20131113 12:33:34|23.34|11.88|33|56789|false|
OFDCFEND
二:DE
DE是余額寶與天弘交互格式,作為一種默認實現。
de協議布局模板
<protocol name="de"><head><row><column><output>${column.desc()}</output><output>:</output><output>${column.value()}</output></column></row><row output="${bodycolumn.horizontal(desc)}" /></head><body><row><column><output>${column.value()}</output></column></row></body><tail><row><column><output>${column.value()}</output></column></row></tail>
</protocol>
- 頭部第一行由
字段描述:字段值
在由分隔符連接而成。 - 頭部第二行由 組件函數
橫向
打印出body的字段描述
。 - 沒有文件尾, 協議可以定義尾部,只要數據定義模板不定義文件尾就行。
de數據定義模板示例
{"head":["totalCount|總筆數|Required|Long","totalAmount|總金額|BigDecimal|Required"],"body":["seq|流水號","instSeq|基金公司訂單號|Required","gmtApply|訂單申請時間|Date:yyyy-MM-dd HH:mm:ss","date|普通日期|Date:yyyyMMdd","dateTime|普通日期時間|Date:yyyyMMdd HH:mm:ss","applyNumber|普通數字|BigDecimal","amount|金額|BigDecimal","age|年齡|Integer","longN|長整型|Long","bol|布爾值|Boolean","memo|備注"],"protocol":"DE"
}
de文件示例
總筆數:2|總金額:300.03
流水號|基金公司訂單號|訂單申請時間|普通日期|普通日期時間|普通數字|金額|年齡|長整型|布爾值|備注
seq_0|inst_seq_0|2013-11-09 12:34:56|20131109|20131112 12:23:34|23.33|10.22|22|123|true|備注1
seq_1|inst_seq_1|2013-11-10 15:56:12|20131110|20131113 12:33:34|23.34|11.88|33|56789|false|
三:fund
國家標準:開放式基金業務數據交換協議
fund協議布局模板
<protocol name="fund" rowsplit="rowSplitByFixedlLength"><head><row columnLayout="vertical"><column><output>${column.value()}</output></column></row><row output="${bodycolumn.count()}" type="Integer|[3,0]" /><row output="${bodycolumn.vertical(name)}" /><row output="${totalCount}" type="Integer|[8,0]" /></head><body><row><column><output>${column.value()}</output></column></row></body><tail><row><column><output>${column.value()}</output></column></row></tail>
</protocol>
- fund協議文件數據是
定長
而不是通過分隔符分割的,不足的補0
。 - protocol標簽的
name
用于指定協議名字,rowsplit
屬性指定數據字段的分割方式。 - row標簽的columnLayout定義了數據定義模板中的字段布局方式,這里是縱向布局,也就是一個字段一行 (默認是橫向布局)。
bodycolumn.count()
是組件實現的內置列的數量。bodycolumn.vertical(name)}
輸出列的字段名
。totalCount
組件內置變量,不用在數據定義模板中定義,數據行數
。- row的
type
屬性定義變量的類型和長度。
fund數據定義模板示例
- OFDCFDAT:開始標志。
- OFDCFEND:結束標志。
{"head":["identity|信息標識|[8,0]|default:OFDCFDAT","version|協議版本號|[4,0]|default:20","msgCreator|信息創建人|[9,0]|default:H0","msgRecipient|信息接收人|[9,0]","sendDate|傳送發生日期|[8,0]|Date:yyyyMMdd","summaryTableNo|匯總表號|[3,0]","fileTypeCode|文件類型代碼 |[2,0]","sender|發送人|[8,0]|default:H0","recipient|接收人|[8,0]"],"body":["TransactionCfmDate|對帳日期|[8,0]|Date:yyyyMMdd","FundCode|基金代碼|[8,0]","AvailableVol|基金可用份數|BigDecimal|[6,2]"],"tail":["fileEnd|數據文件尾部字符|default:OFDCFEND|[8,0]"],"protocol":"FUND"
}
fund文件示例
Map<String, Object> head = new HashMap<String, Object>();
head.put("msgRecipient", "xxx");
head.put("sendDate", "20231122");
head.put("summaryTableNo", "aa");
head.put("fileTypeCode", "bb");
head.put("recipient", "ll");
head.put("totalCount", 1);Map<String, Object> row = new HashMap<String, Object>();
row.put("TransactionCfmDate", "20231122");
row.put("FundCode", "中國1");
// Integer|[6,2] 總長度6位,小數點2位,輸出"004211"
row.put("AvailableVol", 42.11);
OFDCFDAT
20
H0
xxx
20231122
aa
bb
H0
ll
003
TransactionCfmDate
FundCode
AvailableVol
00000001
20231122中國1 004211
OFDCFEND
四:FUND_INDEX
fund_index body數據不是定長數據。
<protocol name="fund_index" rowsplit="rowSplitByFixedlLength"><head><row columnLayout="vertical"><column><output>${column.value()}</output></column></row><row output="${totalCount}" type="Integer|[3,0]" /></head><body><!-- 只有一個字段,定義成vertical 是為了避免調用行分割器, 因為fund_index body數據不是定長數據 --><row columnLayout="vertical"><column><output>${column.value()}</output></column></row></body><tail><row><column><output>${column.value()}</output></column></row></tail>
</protocol>
fund_index數據定義模板示例
{"head": ["identity|信息標識|[8,0]|default:OFDCFIDX","version|協議版本號|[4,0]|default:20","msgCreator|信息創建人|[9,0]|default:H0","msgRecipient|信息接收人|[9,0]","sendDate|傳送發生日期|[8,0]|Date:yyyyMMdd"],"body": ["path|基金文件路徑"],"tail": ["fileEnd|數據文件尾部字符|default:OFDCFEND|[8,0]"],"protocol": "FUND_INDEX"
}
fund_index文件示例
OFDCFIDX
20
H0
xxx
20180302
003
aaa/xxx/ccc
bbb/xxx/ccc
ccc/xxx/ccc
OFDCFEND