Revision 16
Added by Aaron Marcuse-Kubitza about 13 years ago
scripts/xml2db/xml_db.py | ||
---|---|---|
1 | 1 |
# XML-database conversion |
2 | 2 |
|
3 |
import re |
|
3 | 4 |
from xml.dom import Node |
4 | 5 |
|
5 | 6 |
import db_util |
6 | 7 |
import xml_util |
7 |
from xml_util import name_of |
|
8 | 8 |
|
9 |
def name_of(node): return re.sub(r'^.*\.', r'', xml_util.name_of(node)) |
|
10 |
|
|
9 | 11 |
ptr_suffix = '_id' |
10 | 12 |
|
11 | 13 |
def is_ptr(node_name): return node_name.endswith(ptr_suffix) |
... | ... | |
18 | 20 |
assert is_ptr(name_of(node)) |
19 | 21 |
return xml_util.first_elem(node) |
20 | 22 |
|
21 |
def pkey_name(node_name): return node_name+ptr_suffix |
|
22 |
|
|
23 |
def isfield(node_name): return node_name.find('.') >= 0 |
|
24 |
|
|
25 |
def field_name(node_name): |
|
26 |
if isfield(node_name): return node_name.partition('.')[2] |
|
27 |
else: return node_name |
|
28 |
|
|
29 |
def is_db_export(node_name): return node_name.find('.') >= 1 # has prefix |
|
30 |
|
|
31 | 23 |
def find_by_name(node, name): |
32 | 24 |
for parent in xml_util.NodeParentIter(node): |
33 | 25 |
if name_of(parent) == name: return parent |
34 | 26 |
else: |
35 | 27 |
for child in xml_util.NodeElemIter(parent): |
36 |
child_name = field_name(name_of(child))
|
|
28 |
child_name = name_of(child)
|
|
37 | 29 |
if is_ptr(child_name): |
38 | 30 |
if ptr_type(child_name) == name: return ptr_target(child) |
39 | 31 |
elif child_name == name: return child |
... | ... | |
51 | 43 |
|
52 | 44 |
def obj(node): |
53 | 45 |
table = name_of(node) |
54 |
db_util.check_name(table) |
|
55 | 46 |
pkey_ = pkey(table) |
56 | 47 |
row = {} |
57 | 48 |
children = [] |
58 |
iter_ = xml_util.NodeElemIter(node) |
|
59 | 49 |
|
60 |
# Skip any pkey |
|
61 |
child_name = name_of(iter_.curr()) # first child |
|
62 |
if is_db_export(child_name) and is_ptr(child_name)\ |
|
63 |
or field_name(child_name) == pkey: iter_.next() |
|
64 |
|
|
65 | 50 |
# Divide children into fields and children with fkeys to parent |
66 |
for child in iter_: |
|
67 |
if isfield(name_of(child)): row.update([field(child)]) |
|
51 |
for child in xml_util.NodeElemIter(node): |
|
52 |
child_name = name_of(child) |
|
53 |
if xml_util.is_text(child): row[child_name] = xml_util.value(child) |
|
54 |
elif is_ptr(child_name): |
|
55 |
child = ptr_target(child) |
|
56 |
obj(child) |
|
57 |
row[child_name] = xml_util.get_id(child) |
|
68 | 58 |
else: children.append(child) |
59 |
try: del row[pkey_] |
|
60 |
except KeyError: pass |
|
69 | 61 |
|
70 | 62 |
# Add fkey to parent |
71 | 63 |
parent_id = xml_util.get_id(node.parentNode) |
... | ... | |
87 | 79 |
# Insert children with fkeys to parent |
88 | 80 |
for child in children: obj(child) |
89 | 81 |
|
90 |
def field(node): |
|
91 |
if xml_util.is_text(node): value = xml_util.value(node) |
|
92 |
else: |
|
93 |
child = xml_util.first_elem(node) |
|
94 |
obj(child) |
|
95 |
value = xml_util.get_id(child) |
|
96 |
return (field_name(name_of(node)), value) |
|
97 |
|
|
98 | 82 |
row_ct_ref = [0] |
99 | 83 |
main(node) |
100 | 84 |
return row_ct_ref[0] |
Also available in: Unified diff
Changed xml2db to use primarily node contents to determine whether a node is a field or a child table