Revision 2016
Added by Aaron Marcuse-Kubitza almost 13 years ago
lib/xml_func.py | ||
---|---|---|
57 | 57 |
name = node.tagName |
58 | 58 |
if name.startswith('_') and name in funcs: |
59 | 59 |
try: |
60 |
value = funcs[name](xml_dom.NodeTextEntryIter(node)) |
|
60 |
value = funcs[name](xml_dom.NodeTextEntryIter(node), node)
|
|
61 | 61 |
xml_dom.replace_with_text(node, value) |
62 | 62 |
except Exception, e: # also catch non-wrapped exceptions (XML func bugs) |
63 | 63 |
# Save in case another exception raised, overwriting sys.exc_info() |
... | ... | |
86 | 86 |
|
87 | 87 |
#### General |
88 | 88 |
|
89 |
def _ignore(items): |
|
89 |
def _ignore(items, self):
|
|
90 | 90 |
'''Used to "comment out" an XML subtree''' |
91 | 91 |
return None |
92 | 92 |
funcs['_ignore'] = _ignore |
93 | 93 |
|
94 | 94 |
#### Conditionals |
95 | 95 |
|
96 |
def _eq(items): |
|
96 |
def _eq(items, node):
|
|
97 | 97 |
items = dict(items) |
98 | 98 |
try: |
99 | 99 |
left = items['left'] |
... | ... | |
102 | 102 |
return util.bool2str(left == right) |
103 | 103 |
funcs['_eq'] = _eq |
104 | 104 |
|
105 |
def _if(items): |
|
105 |
def _if(items, node):
|
|
106 | 106 |
items = dict(items) |
107 | 107 |
try: |
108 | 108 |
cond = items['cond'] |
... | ... | |
116 | 116 |
|
117 | 117 |
#### Combining values |
118 | 118 |
|
119 |
def _alt(items): |
|
119 |
def _alt(items, node):
|
|
120 | 120 |
items = list(items) |
121 | 121 |
items.sort() |
122 | 122 |
try: return items[0][1] # value of lowest-numbered item |
123 | 123 |
except IndexError: return None # input got removed by e.g. FormatException |
124 | 124 |
funcs['_alt'] = _alt |
125 | 125 |
|
126 |
def _merge(items): |
|
126 |
def _merge(items, node):
|
|
127 | 127 |
items = list(conv_items(strings.ustr, items)) |
128 | 128 |
# get *once* from iter, check types |
129 | 129 |
items.sort() |
130 | 130 |
return maps.merge_values(*[v for k, v in items]) |
131 | 131 |
funcs['_merge'] = _merge |
132 | 132 |
|
133 |
def _label(items): |
|
133 |
def _label(items, node):
|
|
134 | 134 |
items = dict(conv_items(strings.ustr, items)) |
135 | 135 |
# get *once* from iter, check types |
136 | 136 |
value = items.get('value', None) |
... | ... | |
142 | 142 |
|
143 | 143 |
#### Transforming values |
144 | 144 |
|
145 |
def _collapse(items): |
|
145 |
def _collapse(items, node):
|
|
146 | 146 |
'''Collapses a subtree if the "value" element in it is NULL''' |
147 | 147 |
items = dict(items) |
148 | 148 |
try: require = cast(strings.ustr, items['require']) |
... | ... | |
156 | 156 |
|
157 | 157 |
types_by_name = {None: strings.ustr, 'str': strings.ustr, 'float': float} |
158 | 158 |
|
159 |
def _nullIf(items): |
|
159 |
def _nullIf(items, node):
|
|
160 | 160 |
items = dict(conv_items(strings.ustr, items)) |
161 | 161 |
try: null = items['null'] |
162 | 162 |
except KeyError, e: raise SyntaxError(e) |
... | ... | |
187 | 187 |
if new_value == '*': new_value = value # '*' means keep input value the same |
188 | 188 |
return new_value |
189 | 189 |
|
190 |
def _map(items): |
|
190 |
def _map(items, node):
|
|
191 | 191 |
'''See repl() |
192 | 192 |
@param items |
193 | 193 |
<last_entry> Value |
... | ... | |
199 | 199 |
return util.none_if(repl(dict(items), value), u'') # empty value means None |
200 | 200 |
funcs['_map'] = _map |
201 | 201 |
|
202 |
def _replace(items): |
|
202 |
def _replace(items, node):
|
|
203 | 203 |
items = conv_items(strings.ustr, items) # get *once* from iter, check types |
204 | 204 |
value = pop_value(items) |
205 | 205 |
if value == None: return None # input is empty |
... | ... | |
214 | 214 |
|
215 | 215 |
#### Quantities |
216 | 216 |
|
217 |
def _units(items): |
|
217 |
def _units(items, node):
|
|
218 | 218 |
items = conv_items(strings.ustr, items) # get *once* from iter, check types |
219 | 219 |
value = pop_value(items) |
220 | 220 |
if value == None: return None # input is empty |
... | ... | |
239 | 239 |
if start == '' and range_sep == '-': return default # negative number |
240 | 240 |
return tuple(d.strip() for d in (start, end)) |
241 | 241 |
|
242 |
def _rangeStart(items): |
|
242 |
def _rangeStart(items, node):
|
|
243 | 243 |
items = dict(conv_items(strings.ustr, items)) |
244 | 244 |
try: value = items['value'] |
245 | 245 |
except KeyError: return None # input is empty |
246 | 246 |
return parse_range(value)[0] |
247 | 247 |
funcs['_rangeStart'] = _rangeStart |
248 | 248 |
|
249 |
def _rangeEnd(items): |
|
249 |
def _rangeEnd(items, node):
|
|
250 | 250 |
items = dict(conv_items(strings.ustr, items)) |
251 | 251 |
try: value = items['value'] |
252 | 252 |
except KeyError: return None # input is empty |
253 | 253 |
return parse_range(value)[1] |
254 | 254 |
funcs['_rangeEnd'] = _rangeEnd |
255 | 255 |
|
256 |
def _range(items): |
|
256 |
def _range(items, node):
|
|
257 | 257 |
items = dict(conv_items(float, items)) |
258 | 258 |
from_ = items.get('from', None) |
259 | 259 |
to = items.get('to', None) |
... | ... | |
261 | 261 |
return str(to - from_) |
262 | 262 |
funcs['_range'] = _range |
263 | 263 |
|
264 |
def _avg(items): |
|
264 |
def _avg(items, node):
|
|
265 | 265 |
count = 0 |
266 | 266 |
sum_ = 0. |
267 | 267 |
for name, value in conv_items(float, items): |
... | ... | |
277 | 277 |
' allowed for ratio scale data ' |
278 | 278 |
'(see <http://en.wikipedia.org/wiki/Coefficient_of_variation>)') |
279 | 279 |
|
280 |
def _noCV(items): |
|
280 |
def _noCV(items, node):
|
|
281 | 281 |
try: name, value = items.next() |
282 | 282 |
except StopIteration: return None |
283 | 283 |
if re.match('^(?i)CV *\d+$', value): raise FormatException(CvException()) |
... | ... | |
286 | 286 |
|
287 | 287 |
#### Dates |
288 | 288 |
|
289 |
def _date(items): |
|
289 |
def _date(items, node):
|
|
290 | 290 |
items = dict(conv_items(strings.ustr, items)) |
291 | 291 |
# get *once* from iter, check types |
292 | 292 |
try: str_ = items['date'] |
... | ... | |
332 | 332 |
except ValueError, e: raise FormatException(e) |
333 | 333 |
funcs['_date'] = _date |
334 | 334 |
|
335 |
def _dateRangeStart(items): |
|
335 |
def _dateRangeStart(items, node):
|
|
336 | 336 |
items = dict(conv_items(strings.ustr, items)) |
337 | 337 |
try: value = items['value'] |
338 | 338 |
except KeyError: return None # input is empty |
339 | 339 |
return dates.parse_date_range(value)[0] |
340 | 340 |
funcs['_dateRangeStart'] = _dateRangeStart |
341 | 341 |
|
342 |
def _dateRangeEnd(items): |
|
342 |
def _dateRangeEnd(items, node):
|
|
343 | 343 |
items = dict(conv_items(strings.ustr, items)) |
344 | 344 |
try: value = items['value'] |
345 | 345 |
except KeyError: return None # input is empty |
... | ... | |
356 | 356 |
name_parts_slices = dict(_name_parts_slices_items) |
357 | 357 |
name_parts = [name for name, slice_ in _name_parts_slices_items] |
358 | 358 |
|
359 |
def _name(items): |
|
359 |
def _name(items, node):
|
|
360 | 360 |
items = dict(items) |
361 | 361 |
parts = [] |
362 | 362 |
for part in name_parts: |
... | ... | |
364 | 364 |
return ' '.join(parts) |
365 | 365 |
funcs['_name'] = _name |
366 | 366 |
|
367 |
def _namePart(items): |
|
367 |
def _namePart(items, node):
|
|
368 | 368 |
out_items = [] |
369 | 369 |
for part, value in items: |
370 | 370 |
try: slice_ = name_parts_slices[part] |
371 | 371 |
except KeyError, e: raise SyntaxError(e) |
372 | 372 |
out_items.append((part, ' '.join(value.split(' ')[slice_]))) |
373 |
return _name(out_items) |
|
373 |
return _name(out_items, node)
|
|
374 | 374 |
funcs['_namePart'] = _namePart |
375 | 375 |
|
376 | 376 |
#### Angles |
377 | 377 |
|
378 |
def _compass(items): |
|
378 |
def _compass(items, node):
|
|
379 | 379 |
'''Converts a compass direction (N, NE, NNE, etc.) into a degree heading''' |
380 | 380 |
items = dict(conv_items(strings.ustr, items)) |
381 | 381 |
try: value = items['value'] |
... | ... | |
388 | 388 |
|
389 | 389 |
#### Paths |
390 | 390 |
|
391 |
def _simplifyPath(items): |
|
391 |
def _simplifyPath(items, node):
|
|
392 | 392 |
items = dict(items) |
393 | 393 |
try: |
394 | 394 |
next = cast(strings.ustr, items['next']) |
Also available in: Unified diff
xml_func.py: Made all functions take a 2nd node param, which contains the func node itself