[转]
Part 1 - Expressiveness of Simple Transformations
Simple Transformations are a SAP proprietary programming language that is integrated into ABAP by CALL TRANSFORMATION in kernel release 6.40. Its concept differs from other transformation languages, like JiBX, which is used for XML-Java mapping, or languages suitable both for queries and transformations, like Lore, XCerpt, XDuce or even XSLT, which is also supported in ABAP by CALL TRANSFORMATION. By looking at examples of ABAP package SST_DEMO you will understand how ST works. In contrast to XSLT, Simple Transformations (ST) are fast, memory efficient and symmetric, but lack of expressiveness.
Unfortunately I can't describe the power of ST in a mathematical way because, as usual, conditions cause most technical problems and the
So, when I'm asked about expressiveness, usually I tell how many times an ABAP or XML node can be accessed, mention the linear order during processing, lookahead of 1 and so on. If I start to tell about the possibilities to use parameters and breaking symmetry between serilization and deserilization, clever people will start to think how far they can go. A typical question is:
Can I create relational data models from nested structures with an unbounded number of occurrences during deserialization?
This is a natural question when you are doing data exchange with non-SAP systems using standardized XML frameworks and you want to save your data in transparent tables with additional foreign keys. If you are working with small datasets you won't have problems when you copy nested internal tables into the target data structure in ABAP. But let's ask the question if we can avoid heavy postprocessing. Of course, I would accept a pragmatic solution. Simple post processing in ABAP without copying data from one internal table into another would be acceptable.
The answer to the question above is, "no chance. You have to do heavy post processing." The reason is very simple and has to do with the
A typical example for a ST is to transform this XML document into an internal table whose table line contains an component 'nummer' and another internal table:
Note that the transformation above is symmetric and can be used in both directions to serialize and deserialize.
If we want to transform the XML stream above to a relational data model first we have to break up the nested structure. The values of elements have to be put into one internal table and then
Internal table for elements:
Counter calculated afterwards
Value of element
A1
A2
Internal table for
Additional mark
Value of element
+
01
+
02
-
03
Now we can do two loops in ABAP. At first we increment the counter for our elements and then introduce a counter for our
Internal table for elements:
Counter during postprocessing
Value of element
1
A1
2
A2
Internal table for
Additional mark after postprocessing
Value of element
1
01
1
02
2
03
So let's start to code. The following transformation does this job without calculating alternating marks. Just have a look at the inner loop. We change the root from ROOT1 to ROOT2:
Then we test it with following quick-hack:
DATA xml_string TYPE string.
data: begin of z,
mark type c,
nummer type string,
end of z.
data: begin of a,
counter type i,
name type string,
zl like table of z,
end of a.
data t_a like table of a.
data t_z like table of z.
xml_string = `` &
`
`` &
`
CALL TRANSFORMATION my_first
SOURCE XML xml_string
RESULT ROOT1 = t_a
ROOT2 = t_z.
The result is annoying. The internal table t_a contains data of two elements but t_z had only one entry with value "03".
The explanation is simple. When you want to deal with internal tables you have to use
In the following I want to mention a second aspect that seems to be confusing when you are confronted with ST for the first time.
You can assign the value of an element during deserilization only once!
In the rest of this issue we try to solve following task -- we want to deserialize the content of the
If you run this transformation you won't get the expected result. Why? Compared to XSLT, variables in ST behave like variables in any other procedural language and you can assign them for more than one time. But following two lines doesn't work:
<tt:value ref="$a.name"/>
<tt:read type="C" var="N"/>
First you want to read it into an ABAP structure and then bind it to a variable. Even changing the order of the two commands wouldn't help you. Let's test it with an easier example:
Here is the ABAP code for running this ST:
DATA xml_string TYPE string.
DATA field1 TYPE string.
DATA field2 TYPE string.
xml_string = `
CALL TRANSFORMATION my_transformation
SOURCE XML xml_string
RESULT ROOT1 = field1
ROOT2 = field2.
You will verify that ROOT2 is empty afterwards, so this doesn't work. Therefore we have to find another solution to implement our transformation, perhaps using the condition construct. But here we have another problem; the template content of the conditional is either a template (then you can't do assignments to variables for example) or it is evaluated unconditionally during deserialization. So, in fact, I can't tell you whether this will lead to success.
Summary
So let's summarize what we have learned. Programming ST is not difficult and ST does a great job transforming an XML document into nested ABAP structures, back and forth, because it is designed for this task. So to be honest, it's not surprising that transformations to a relational model is impossible without heavy post processing because for this task we have to create a set of internal tables from an XML tree and have to add foreign keys. In our small example above those keys are not part of our model so we would have to generate them and, of course, break the symmetry of our transformation thereby. The impossibility is caused by the fact that we can't increment variables and we can't append deserialized data to an internal table.
If we want to describe the (lack of) power of Simple Transformations I suggest to collect some simple examples for transformations we can't realize with ST and reduce other problems to them.
But does the lack of expressiveness really bother you? I don't believe in solutions that can solve every problem without causing new problems. Perhaps some new features that could help us will be added to ST in post 6.40 development but designers will have to be careful not to make the language too complex.
On the other hand, a software developer should try to choose the right technology -- iXML, XSLT, XSLT with ABAP calls or Java enhancement, ST or even JAXB -- and not to misuse a certain technology to create programs that can solve a problem in an unexpected way but are hard to understand and possibly difficult to maintain.
Check back soon for part 2 of this series!
手机扫一扫
移动阅读更方便
你可能感兴趣的文章