1 """
2 xmlstan elements of VOTable.
3 """
4
5
6
7
8
9
10
11 from gavo import utils
12 from gavo.utils import ElementTree
13 from gavo.utils.stanxml import (
14 Element, registerPrefix, getPrefixInfo, schemaURL, escapePCDATA)
15 from gavo.votable import common
16
17
18 NAMESPACES = {
19 "1.3": "http://www.ivoa.net/xml/VOTable/v1.3",
20 "1.2": "http://www.ivoa.net/xml/VOTable/v1.2",
21 "1.1": "http://www.ivoa.net/xml/VOTable/v1.1",
22 }
23
24
25
26 registerPrefix("vot", NAMESPACES["1.3"], schemaURL("VOTable-1.3.xsd"))
27 registerPrefix("vot2", NAMESPACES["1.2"], schemaURL("VOTable-1.2.xsd"))
28 registerPrefix("vot1", NAMESPACES["1.1"], schemaURL("VOTable-1.1.xsd"))
32 """extra VODML element, slated for VOTable 1.4.
33 """
38
39 - class VODML(_VODMLElement):
41
42 - class MODEL(_VODMLElement):
44
47
50
51 - class NAME(_VODMLElement):
53
54 - class URL(_VODMLElement): pass
55
59
63
64 - class IDREF(_VODMLElement): pass
65
70
75
80
83
87
90 """The container for VOTable elements.
91 """
95
97 _a_ID = None
98 _a_ref = None
99 _a_name = None
100 _a_ucd = None
101 _a_utype = None
102 _mayBeEmpty = True
103
105 """returns some name-like thing for a FIELD or PARAM.
106 """
107 if self.name:
108 res = self.name
109 elif self.ID:
110 res = self.ID
111 else:
112 res = "%s_%s"%(self.__class__.__name__, "%x"%id(self))
113 return res.encode("ascii", "ignore")
114
122
124 _a_unit = None
125 _a_xtype = None
126
128 _a_ref = None
129 _a_arraysize = None
130 _a_datatype = None
131 _a_precision = None
132 _a_ref = None
133 _a_type = None
134 _a_width = None
135 _a_format = None
136
138 return self.arraysize is None or self.arraysize=='1'
139
142
145
147 """returns the number of items one should expect in value, or
148 None for variable-length arrays.
149 """
150 return common.getLength(self.arraysize)
151
154
156 """sets the null literal of self to val.
157 """
158 valEls = list(self.iterChildrenWithName("VALUES"))
159 if valEls:
160 valEls[0](null=val)
161 else:
162 self[VOTable.VALUES(null=val)]
163
169
170 - class _ContentElement(_VOTElement):
171 """An element containing tabular data.
172
173 These are usually serialized using some kind of streaming.
174
175 See votable.tablewriter for details.
176 """
177 - def write(self, file):
178 raise NotImplementedError("This _ContentElement cannot write yet")
179
180
182 """a base class for both BINARY and BINARY2.
183 """
184 _childSequence = ["STREAM"]
185 encoding = "base64"
186
188
189
190 blockSize = 57
191 buf, bufFil, flushThreshold = [], 0, blockSize*20
192 file.write('<%s>'%self.name_)
193 file.write('<STREAM encoding="base64">')
194 try:
195 for data in self.iterSerialized():
196 buf.append(data)
197 bufFil += len(data)
198 if bufFil>flushThreshold:
199 curData = ''.join(buf)
200 curBlockLen = (len(curData)//blockSize)*blockSize
201 file.write(curData[:curBlockLen].encode("base64"))
202 buf = [curData[curBlockLen:]]
203 finally:
204 file.write("".join(buf).encode("base64"))
205 file.write("</STREAM>")
206 file.write('</%s>'%self.name_)
207
208 - class BINARY(_BinaryDataElement):
210
211 - class BINARY2(_BinaryDataElement):
213
220
227
228 - class TYPE(_VOTElement):
230
231 - class ROLE(_VOTElement):
233
234 - class DATA(_VOTElement):
235 _childSequence = ["INFO", "TABLEDATA", "BINARY", "BINARY2", "FITS"]
236
239
242
243 - class FIELD(_TypedElement):
245
247
248 - class FITS(_VOTElement):
250
251 - class GROUP(_DescribedElement):
256
257
258 - class INFO(_ValuedElement):
265
267
268
269 name_ = "INFO"
270
271 - class LINK(_VOTElement):
285
286
287 - class MAX(_VOTElement):
294
295
296 - class MIN(_VOTElement):
303
304
310
311
312 - class PARAM(_TypedElement):
317
318
320
321
323 _a_ID = None
324 _a_name = None
325 _a_type = None
326 _a_utype = None
327 _childSequence = ["DESCRIPTION", "VODML", "DEFINITIONS",
328 "INFO", "COOSYS", "TIMESYS", "GROUP",
329 "PARAM", "LINK", "TABLE", "INFO_atend", "RESOURCE", "stub"]
330
331
333 outputFile.write(
334 """<INFO name="QUERY_STATUS" value="ERROR">%s</INFO>"""%
335 escapePCDATA("Error while serializing VOTable,"
336 " content is probably incomplete: %s"%
337 utils.safe_str(exception)))
338
339
348
349
350 - class TABLE(_DescribedElement):
351 """A TABLE element.
352
353 If you want to access fields by name (getFieldForName), make sure
354 name and ids are unique.
355 """
356 _a_nrows = None
357 _childSequence = ["DESCRIPTION", "INFO", "GROUP", "FIELD", "PARAM", "LINK",
358 "DATA", "stub"]
359
360 _fieldIndex = None
361
362 @utils.memoized
365
376
378 """returns the FIELD having a name or id of name.
379
380 A KeyError is raised when the field does not exist; if names are
381 not unique, the last column with the name specified is returned.
382 """
383 return self._getFieldIndex()["name"]
384
385
398
399
400 - class TD(_VOTElement):
404
405
406 - class TR(_VOTElement):
409
410
419
420
436
437
454
468
469
470
471 -def voTag(tagName, version="1.3"):
472 """returns the VOTable QName for tagName.
473
474 You only need this if you want to search in ElementTrees.
475 """
476 return ElementTree.QName(NAMESPACES[version], tagName)
477