1
|
When element types represent hierarchy that exists in the XML document
|
2
|
but not in the database, they can be eliminated by "passing-through"
|
3
|
the unwanted elements -- that is, by treating their properties as if
|
4
|
they were properties of their parent. For example, suppose a Customer
|
5
|
element type has the following structure:
|
6
|
|
7
|
<Customer>
|
8
|
<Name>ABC Incorporated</Name>
|
9
|
<Address>
|
10
|
<Street>123 Main St.</Street>
|
11
|
<City>Chicago</City>
|
12
|
<State>IL</State>
|
13
|
<PostCode>60609</PostCode>
|
14
|
<Country>USA</Country>
|
15
|
</Address>
|
16
|
</Customer>
|
17
|
|
18
|
Under the standard tree-of-objects view used by XML-DBMS, Address
|
19
|
requires its own table. But what if the street, city, state, etc.
|
20
|
existed as columns in the Customer table? It is relatively easy to
|
21
|
eliminate the Address element and treat its children as properties
|
22
|
of the Customer element. The problem with this is that there is no
|
23
|
general solution for reconstructing passed-through elements when
|
24
|
retrieving data from the database. In the case above, we know that
|
25
|
there is a single Address element and that Street, City, etc. are
|
26
|
its children. Now imagine the case in which an element A can have
|
27
|
multiple children B, each of which can have multiple children C:
|
28
|
|
29
|
<A>
|
30
|
<B>
|
31
|
<C>...</C>
|
32
|
<C>...</C>
|
33
|
</B>
|
34
|
<B>
|
35
|
<C>...</C>
|
36
|
<C>...</C>
|
37
|
</B>
|
38
|
</A>
|
39
|
|
40
|
If we pass through the element B, we store four C's in the database
|
41
|
as properties of A. However, when retrieving the C's from the database,
|
42
|
we have no way of knowing whether these all came from a single B, they
|
43
|
can from the two B's shown above, or they came from four different B's.
|
44
|
|
45
|
In the simple case -- a passed-through element occurs exactly once in
|
46
|
its parent -- the following mapping language constructions can be used
|
47
|
to pass-through an element type:
|
48
|
|
49
|
<!ELEMENT ClassMap (ElementType,
|
50
|
(ToRootTable | ToClassTable),
|
51
|
PropertyMap*, RelatedClass*, PassThrough*)>
|
52
|
|
53
|
<!ELEMENT PassThrough (ElementType,
|
54
|
PropertyMap*, RelatedClass*, PassThrough*,
|
55
|
OrderColumn?)>
|
56
|
|
57
|
Note that a PassThrough element looks almost the same as a ClassMap.
|
58
|
This is not surprising, as the passed-through element is simply an
|
59
|
element type-as-class that does not have its own table. For example,
|
60
|
the following declares that the Address element type is to be passed
|
61
|
through. Like element types-as-properties, passed-through element
|
62
|
types are mapped on a per-parent basis, so this map is nested inside
|
63
|
the class map for Customer.
|
64
|
|
65
|
<PassThrough>
|
66
|
<ElementType Name="Address"/>
|
67
|
<PropertyMap>
|
68
|
<ElementType Name="Street"/>
|
69
|
<ToColumn>
|
70
|
<Column Name="Street"/>
|
71
|
</ToColumn>
|
72
|
</PropertyMap>
|
73
|
...other property maps...
|
74
|
...related class maps...
|
75
|
...pass-through maps...
|
76
|
</PassThrough>
|
77
|
|
78
|
The first ElementType element gives the name of the passed through
|
79
|
element type. Because passed-through element types are viewed as
|
80
|
classes, the PassThrough element must map the properties, related
|
81
|
classes, and passed-through child classes of the passed-through
|
82
|
class, just like a class map does. Shown above is a property map
|
83
|
that maps the Street element type to the Street column of the
|
84
|
parent table (Customers).
|
85
|
|
86
|
There are a number of comments in the code to show where/how
|
87
|
pass-through can be implemented. When transferring data to the
|
88
|
database, the function to get a child element needs to check if
|
89
|
the next child is pass-through. If so, the children of that element
|
90
|
are processed immediately. That is, the grandchildren of the element
|
91
|
being processed are treated as if they were children. When
|
92
|
transferring data from the database, properties need to be checked
|
93
|
to see if they have a pass-through parent; if so, the parent needs
|
94
|
to be reconstructed before the children are added. Note that, in the
|
95
|
case of children of passed-through elements, order refers to the
|
96
|
order in the passed-through element, not the grandparent.
|