Simple Transformations
簡介
ST語言是一種描述ABAP 和XML之間格式轉換的編程語言,用於ABAP數據的序列化(ABAP->XML)和反序列化(XML->ABAP)。
ST程序可以通過轉換編輯器進行編輯(TCODE: STRANS),優點:ST程序很容易閱讀;串行訪問XML數據,因此即使數據量很大,也非常高效;ST程序同時描述序列化和反序列化,即用XML序列化的ABAP數據也可以用ST程序反序列化;僅限於基本和結構化ABAP數據以及內部表的轉換。
創建一個Simple Transformation
TCODE: STRANS
創建一個transformation之後,有一些初始語句,再此界面根據要解析的XML編寫程序,
第一行<?>用於標識轉換(自動插入)
第二行transform代表根元素,xmlns後面代表命名空間,tt作爲此空間中的約定。
語法
<tt:transform [template="tmpl"]>
...
</tt:transform>
根元素的關鍵字,可以指定模板屬性的名稱(可選),指定名稱的模板作爲主模板,如果未指定,沒有名字的模板作爲主模板。
<tt:template [name="tmpl"]>
...
</tt:template>
定義了一個模板,ST程序至少包含一個模板,模板必須名稱是不一樣的(沒有名稱的模板只能有一個),模板名稱不區分大小寫。
主模板的內容表示ABAP數據序列化或數據反序列化所依據的XML數據的結構。
模板的內容可以由文本XML元素和ST命令組成。
<tt:root name="..." [[line-]type="..."
[length="..."]
[decimals="..."]]
[...] />
ST程序必須至少包含一個模板外部的數據根聲明。
數據根是ST程序與ABAP數據對象的接口,在語句調用轉換中指定爲源或目標字段。
數據根使用語句tt:root定義。必須使用name屬性將名稱分配給數據根。
在tt:transform級別聲明的數據根構成主模板的上下文,可以直接在其中尋址。
子模板中無法識別數據根。但是,當調用這些模板時,它們可以綁定到子模板的本地數據根。
每個數據根都有自己的樹結構,可用於處理綁定數據對象的組件。尋址數據根的子節點相當於引用綁定到數據根的數據對象的組件。各個數據根的樹結構彼此獨立。
單個樹結構中數據節點的尋址總是從數據根開始。
每個模板都使用自己的樹結構。只有主模板使用在轉換級別聲明的數據根,這些根在轉換期間直接綁定到ABAP數據對象。調用子模板時,本地數據根將綁定到調用方的當前數據節點。
[tt:]ref
使用命令設置當前節點
<tt:ref name="node">
...
</tt:ref>
使用屬性設置當前節點
<tt:... ref="node">
...
</tt:...>
在文本XML元素中設置當前節點
<... tt:ref="node">
...
</...>
<tt:value [ref="node"] [map="..."]
[length|minLength|maxLength="len"]
[xsd-type...] />
Value語法用於獲取結構中的具體值,通常與ref共用。
<tt:transform
xmlns:tt="http://www.sap.com/transformation-templates">
<tt:root name="ROOT"/>
<tt:template>
<X tt:ref="ROOT">
<X1>
<tt:value ref="COL1" />
</X1>
<X2>
<tt:value ref="COL2" />
</X2>
<X3 tt:ref="STRUC2">
<X1>
<tt:value ref="COL1" />
</X1>
<X2>
<tt:value ref="COL2" />
</X2>
</X3>
</X>
</tt:template>
</tt:transform>
<tt:loop [ref="node"] [name="alias"]>
...
</tt:loop>
內部表在循環中進行序列化和反序列化,該循環將當前節點設置爲當前錶行。
name屬性可用於定義循環中當前節點的別名。在tt:loop循環中,可以使用$alias對當前節點進行尋址。
例1:
程序
DATA: BEGIN OF struc1,
x1 TYPE string,
x2 TYPE string,
BEGIN OF struc2,
col1 TYPE string,
col2 TYPE string,
END OF struc2,
END OF struc1.
DATA: lv_xml TYPE string.
DATA: lt_xml TYPE STANDARD TABLE OF string.
DATA: l_cx_st_error TYPE REF TO cx_st_error,
e_message TYPE char255.
PARAMETERS p_file TYPE string DEFAULT 'C:\Users\10156700c\Desktop\test2.xml'.
cl_gui_frontend_services=>gui_upload(
EXPORTING
filename = p_file
filetype = 'ASC'
CHANGING
data_tab = lt_xml
EXCEPTIONS
OTHERS = 19 ).
CONCATENATE LINES OF lt_xml INTO lv_xml SEPARATED BY space.
TRY.
CALL TRANSFORMATION zhu_xml_test2
SOURCE XML lv_xml
RESULT root = struc1.
CATCH cx_st_error.
CALL METHOD l_cx_st_error->get_text
RECEIVING
result = e_message.
ENDTRY.
ST程序:
<?sap.transform simple?>
<tt:transform xmlns:tt="http://www.sap.com/transformation-templates" template="temp">
<tt:root name="ROOT"/>
<tt:template name="temp">
<X>
<X1>
<tt:value ref="ROOT.X1"/>
</X1>
<X2>
<tt:value ref="ROOT.X2"/>
</X2>
<X2>
<tt:copy ref="ROOT.STRUC2"/>
</X2>
</X>
</tt:template>
</tt:transform>
XML:
<?xml version="1.0" encoding="utf-8"?>
<X>
<X1>ABCDEFGHIJ</X1>
<X2>111</X2>
<X2>
<COL1>2020-05-28</COL1>
<COL2>08:40:00</COL2>
</X2>
</X>
例2:
TYPES: BEGIN OF ty_value,
value TYPE i,
END OF ty_value.
TYPES: BEGIN OF line,
key TYPE i,
values TYPE TABLE OF ty_value WITH DEFAULT KEY,
END OF line.
DATA itab TYPE TABLE OF line .
DATA result LIKE itab.
DATA lv_xml TYPE string..
DATA lt_xml TYPE STANDARD TABLE OF string.
DATA: l_cx_st_error TYPE REF TO cx_st_error,
e_message TYPE char255.
PARAMETERS p_file TYPE string DEFAULT 'C:\Users\10156700c\Desktop\test1.xml'.
"Load xml file
cl_gui_frontend_services=>gui_upload(
EXPORTING
filename = p_file
filetype = 'ASC'
CHANGING
data_tab = lt_xml
EXCEPTIONS
OTHERS = 19 ).
CONCATENATE LINES OF lt_xml INTO lv_xml SEPARATED BY space.
TRY.
*& 調用 Transformation解析XML數據串
CALL TRANSFORMATION zhu_xml_test1
SOURCE XML lv_xml
RESULT root = itab.
CATCH cx_st_error INTO l_cx_st_error.
CALL METHOD l_cx_st_error->get_text
RECEIVING
result = e_message.
ENDTRY.
ST程序:
<?sap.transform simple?>
<tt:transform xmlns:tt="http://www.sap.com/transformation-templates">
<tt:root name="ROOT"/>
<tt:template>
<tab1>
<tt:loop name="line" ref=".ROOT">
<key>
<tt:value ref="$line.key"/>
</key>
<tab2>
<tt:loop ref="$line.values">
<value>
<tt:value ref="value"/>
</value>
</tt:loop>
</tab2>
</tt:loop>
</tab1>
</tt:template>
</tt:transform>
XML:
<?xml version="1.0" encoding="UTF-8"?>
<tab1>
<key>2</key>
<tab2>
<value>4</value>
<value>8</value>
<value>16</value>
</tab2>
<key>3</key>
<tab2>
<value>9</value>
<value>27</value>
<value>81</value>
</tab2>
<key>4</key>
<tab2>
<value>16</value>
<value>64</value>
<value>256</value>
</tab2>
</tab1>
例3:
TYPES BEGIN OF lty_items.
TYPES qty TYPE string.
TYPES soh TYPE string.
TYPES ean TYPE string.
TYPES soi TYPE string.
TYPES cat TYPE string.
TYPES END OF lty_items.
TYPES BEGIN OF lty_head.
TYPES name TYPE string.
TYPES END OF lty_head.
TYPES BEGIN OF lty_out.
TYPES head TYPE lty_head.
TYPES items TYPE STANDARD TABLE OF lty_items WITH DEFAULT KEY.
TYPES END OF lty_out.
DATA lv_xml TYPE string..
DATA lt_xml TYPE STANDARD TABLE OF string.
DATA ls_out TYPE lty_out.
DATA lt_out TYPE STANDARD TABLE OF lty_out.
DATA: l_cx_st_error TYPE REF TO cx_st_error,
e_message TYPE char255.
PARAMETERS p_file TYPE string DEFAULT 'C:\Users\10156700c\Desktop\test.xml'.
"Load xml file
cl_gui_frontend_services=>gui_upload(
EXPORTING
filename = p_file
filetype = 'ASC'
CHANGING
data_tab = lt_xml
EXCEPTIONS
OTHERS = 19 ).
CONCATENATE LINES OF lt_xml INTO lv_xml SEPARATED BY space.
TRY.
*& 調用 Transformation解析XML數據串
CALL TRANSFORMATION zhu_xml_test
SOURCE XML lv_xml
RESULT file = ls_out.
CATCH cx_st_error INTO l_cx_st_error.
CALL METHOD l_cx_st_error->get_text
RECEIVING
result = e_message.
ENDTRY.
ST程序:
<?sap.transform simple?>
<tt:transform xmlns:tt="http://www.sap.com/transformation-templates">
<tt:root name="FILE"/>
<tt:template>
<FILE tt:ref=".FILE">
<HEAD tt:ref="HEAD">
<NAME tt:value-ref="NAME"/>
</HEAD>
<ITEMS>
<tt:loop ref="ITEMS">
<ITM>
<tt:group>
<tt:cond frq="?">
<tt:attribute name="QTY" value-ref="QTY"/>
</tt:cond>
<tt:cond frq="?">
<tt:attribute name="SOH" value-ref="SOH"/>
</tt:cond>
<tt:cond frq="?">
<tt:attribute name="EAN" value-ref="EAN"/>
</tt:cond>
<tt:cond frq="?">
<tt:attribute name="SOI" value-ref="SOI"/>
</tt:cond>
<tt:cond frq="?">
<tt:attribute name="CAT" value-ref="CAT"/>
</tt:cond>
</tt:group>
</ITM>
</tt:loop>
</ITEMS>
</FILE>
</tt:template>
</tt:transform>
XML:
<?xml version="1.0" encoding="UTF-8"?>
<FILE>
<HEAD>
<NAME>PAB014</NAME>
</HEAD>
<ITEMS>
<ITM CAT="BL" EAN="123123123123" QTY="23"/>
<ITM CAT="" EAN="123123123123" QTY="100"/>
<ITM CAT="" EAN="123123123123" QTY="240"/>
<ITM CAT="" EAN="123123123123" QTY="989"/>
<ITM CAT="" EAN="123123123123" QTY="1000"/>
<ITM CAT="BL" EAN="123123123123" QTY="5"/>
<ITM CAT="" EAN="123123123123" QTY="50" SOI="000010" SOH="4000299949"/>
<ITM CAT="" EAN="123123123123" QTY="140"/>
<ITM CAT="QI" EAN="123123123123" QTY="420"/>
<ITM CAT="" EAN="123123123123" QTY="30"/>
<ITM CAT="QI" EAN="123123123123" QTY="20"/>
<ITM CAT="" EAN="123123123123" QTY="475" SOI="000040" SOH="4000299949"/>
<ITM CAT="" EAN="123123123123" QTY="300"/>
<ITM CAT="" EAN="123123123123" QTY="994"/>
<ITM CAT="BL" EAN="123123123123" QTY="24"/>
<ITM CAT="BL" EAN="123123123123" QTY="3"/>
<ITM CAT="" EAN="123123123123" QTY="441"/>
<ITM CAT="QI" EAN="123123123123" QTY="240"/>
<ITM CAT="" EAN="123123123123" QTY="5"/>
<ITM CAT="BL" EAN="123123123123" QTY="102"/>
<ITM CAT="" EAN="123123123123" QTY="2"/>
<ITM CAT="QI" EAN="123123123123" QTY="360"/>
<ITM CAT="" EAN="123123123123" QTY="403"/>
<ITM CAT="" EAN="6941023243415" QTY="425" SOI="000030" SOH="123123123123"/>
<ITM CAT="" EAN="123123123123" QTY="100"/>
<ITM CAT="" EAN="123123123123" QTY="220"/>
<ITM CAT="" EAN="123123123123" QTY="1000"/>
<ITM CAT="BL" EAN="123123123123" QTY="25" SOI="000020" SOH="4000299949"/>
<ITM CAT="" EAN="123123123123" QTY="425" SOI="000020" SOH="4000299949"/>
<ITM CAT="" EAN="123123123123" QTY="340"/>
<ITM CAT="BL" EAN="123123123123" QTY="1"/>
</ITEMS>
</FILE>
例4:
TYPES: BEGIN OF day,
name TYPE string,
work(1) TYPE c,
END OF day.
DATA: BEGIN OF week,
day1 TYPE day,
day2 TYPE day,
day3 TYPE day,
day4 TYPE day,
day5 TYPE day,
day6 TYPE day,
day7 TYPE day,
END OF week.
DATA: lv_xml TYPE string.
DATA: lt_xml TYPE STANDARD TABLE OF string.
DATA: l_cx_st_error TYPE REF TO cx_st_error,
e_message TYPE char255.
PARAMETERS p_file TYPE string DEFAULT 'C:\Users\10156700c\Desktop\test3.xml'.
cl_gui_frontend_services=>gui_upload(
EXPORTING
filename = p_file
filetype = 'ASC'
CHANGING
data_tab = lt_xml
EXCEPTIONS
OTHERS = 19 ).
CONCATENATE LINES OF lt_xml INTO lv_xml SEPARATED BY space.
TRY.
CALL TRANSFORMATION zhu_xml_test3
SOURCE XML lv_xml
RESULT root = week.
CATCH cx_st_error.
CALL METHOD l_cx_st_error->get_text
RECEIVING
result = e_message.
ENDTRY.
ST程序:
<?sap.transform simple?>
<tt:transform xmlns:tt="http://www.sap.com/transformation-templates" template="TEMP_MAIN">
<tt:root name="ROOT"/>
<tt:template name="TEMP_MAIN">
<week>
<day1 tt:ref="ROOT.DAY1">
<tt:apply name="TEMP_SUB"/>
</day1>
<day2 tt:ref="ROOT.DAY2">
<tt:apply name="TEMP_SUB"/>
</day2>
<day3 tt:ref="ROOT.DAY3">
<tt:apply name="TEMP_SUB"/>
</day3>
<day4 tt:ref="ROOT.DAY4">
<tt:apply name="TEMP_SUB"/>
</day4>
<day5 tt:ref="ROOT.DAY5">
<tt:apply name="TEMP_SUB"/>
</day5>
<day6 tt:ref="ROOT.DAY6">
<tt:apply name="TEMP_SUB"/>
</day6>
<day7 tt:ref="ROOT.DAY7">
<tt:apply name="TEMP_SUB"/>
</day7>
</week>
</tt:template>
<tt:template name="TEMP_SUB">
<name>
<tt:value ref="name"/>
</name>
<work>
<tt:value ref="work"/>
</work>
</tt:template>
</tt:transform>
XML:
<?xml version="1.0" encoding="UTF-8"?>
<week>
<day1>
<name>Monday</name>
<work>X</work>
</day1>
<day2>
<name>Tuesday</name>
<work>X</work>
</day2>
<day3>
<name>Wednesday</name>
<work>X</work>
</day3>
<day4>
<name>Thursday</name>
<work>X</work>
</day4>
<day5>
<name>Friday</name>
<work>X</work>
</day5>
<day6>
<name>Saturday</name>
<work/>
</day6>
<day7>
<name>Sunday</name>
<work/>
</day7>
</week>