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>