1
2
3
4
5
6
7
8
9
10
11
12
13 """
14 Interface to normalized Data Elements
15 """
16
17 import os, os.path
18
19
20 import cPickle
21 import libxml2
22 from stat import ST_MTIME
23
24
25 from pyx12.errors import EngineError, XML_Reader_Error
26
28 """Class for data elements module errors."""
29
30 NodeType = {'element_start': 1, 'element_end': 15, 'attrib': 2, 'text': 3, \
31 'CData': 4, 'entity_ref': 5, 'entity_decl':6, 'pi': 7, 'comment': 8, \
32 'doc': 9, 'dtd': 10, 'doc_frag': 11, 'notation': 12}
33
35 """
36 Interface to normalized Data Elements
37 """
38
40 """
41 Initialize the list of data elements
42 @param base_path: path to dataele.xml
43 @type base_path: string
44
45 @note: self.dataele - map to the data element
46 {ele_num: (data_type, min_len, max_len, name)}
47 """
48
49 self.dataele = {}
50 code_file = os.path.join(base_path, 'dataele.xml')
51 pickle_file = '%s.%s' % (os.path.splitext(code_file)[0], 'pkl')
52
53 ele_num = None
54 data_type = None
55 min_len = None
56 max_len = None
57 name = None
58
59 try:
60 if os.stat(code_file)[ST_MTIME] < os.stat(pickle_file)[ST_MTIME]:
61 self.dataele = cPickle.load(open(pickle_file))
62 else:
63 raise DataElementsError, "reload data elements"
64 except:
65 try:
66 reader = libxml2.newTextReaderFilename(code_file)
67 except:
68 raise EngineError, 'Data Element file not found: %s' % (code_file)
69 try:
70 ret = reader.Read()
71 if ret == -1:
72 raise XML_Reader_Error, 'Read Error'
73 elif ret == 0:
74 raise XML_Reader_Error, 'End of Map File'
75 while ret == 1:
76 if reader.NodeType() == NodeType['element_start']:
77 cur_name = reader.Name()
78 if cur_name == 'data_ele':
79 while reader.MoveToNextAttribute():
80 if reader.Name() == 'ele_num':
81 ele_num = reader.Value()
82 elif reader.Name() == 'data_type':
83 data_type = reader.Value()
84 elif reader.Name() == 'min_len':
85 min_len = int(reader.Value())
86 elif reader.Name() == 'max_len':
87 max_len = int(reader.Value())
88 elif reader.Name() == 'name':
89 name = reader.Value()
90 if ele_num is None or data_type is None or \
91 min_len is None or max_len is None or \
92 name is None:
93 raise EngineError, 'Invalid Data Element %s' \
94 % (ele_num)
95 self.dataele[ele_num] = (data_type, min_len, max_len)
96 elif reader.NodeType() == NodeType['element_end']:
97 if cur_name == 'data_ele':
98 ele_num = None
99 data_type = None
100 min_len = None
101 max_len = None
102 name = None
103 ret = reader.Read()
104 if ret == -1:
105 raise XML_Reader_Error, 'Read Error'
106 elif ret == 0:
107 raise XML_Reader_Error, 'End of Map File'
108 except XML_Reader_Error:
109 pass
110
111
113 """
114 Get the element characteristics for the indexed element code
115 @param ele_num: the data element code
116 @type ele_num: string
117 @return: (data_type, min_len, max_len)
118 @rtype: (string, int, int)
119 """
120 if not ele_num:
121 raise EngineError, 'Bad data element %s' % (ele_num)
122 if not self.dataele.has_key(ele_num):
123 raise EngineError, 'Data Element "%s" is not defined' \
124 % (ele_num)
125
126
127
128
129 return self.dataele[ele_num]
130
132 for ele_num in self.dataele.keys():
133 print self.dataele[ele_num]
134
137