2016-07-25 11:01:19 -04:00

923 lines
32 KiB
Python

from __future__ import (absolute_import, division, print_function)
from owslib.etree import etree
from owslib.util import nspath, testXMLValue, openURL
from owslib.util import xml_to_dict as _xml_to_dict
from datetime import datetime
from dateutil import parser
namespaces = {
'wml1.1':'{http://www.cuahsi.org/waterML/1.1/}',
'wml1.0':'{http://www.cuahsi.org/waterML/1.0/}',
'xsi':'{http://www.w3.org/2001/XMLSchema-instance',
'xsd':'{http://www.w3.org/2001/XMLSchema'
}
def ns(namespace):
return namespaces.get(namespace)
class XMLParser(object):
"""
Convienence class; provides some useful shortcut methods to make retrieving xml elements from etree
a little easier.
"""
def __init__(self,xml_root,namespace):
try:
self._root = etree.parse(xml_root)
except:
self._root = xml_root
if not namespace in namespaces:
raise ValueError('Unsupported namespace passed in to parser!')
self._ns = namespace
def _find(self,tofind):
try:
return self._root.find(namespaces.get(self._ns) + tofind)
except:
return None
def _findall(self,tofind):
try:
return self._root.findall(namespaces.get(self._ns) + tofind)
except:
return None
class SitesResponse(XMLParser):
"""
Parses the response from a 'GetSites' request
Parameters
===========
:xmlio - A file-like object that holds the xml response from the request.
Return
=======
An object constructed from a dictionary parse of the response. The object has get access and can iterate
over the sites returned.
"""
def __init__(self,xml,version='wml1.1'):
super(SitesResponse,self).__init__(xml,version)
self.parse_sites_response()
def __iter__(self):
for s in self.sites:
yield s
def __getitem__(self,key):
if isinstance(key,int) and key < len(self.sites):
return self.sites[key]
if isinstance(key,str):
site = [site for site in self.sites for code in site.site_info.site_codes if code == key]
if len(site) > 0:
return site[0]
raise KeyError('Unknown key ' + str(key))
def parse_sites_response(self,xml=None):
"""
"""
if xml is not None:
try:
self._root = etree.parse(xml)
except:
self._root = xml
# try:
self.query_info = QueryInfo(self._find('queryInfo'), self._ns)
self.sites = [Site(site, self._ns) for site in self._findall('site')]
# except:
# raise ValueError('Cannot parse sitesResponse element correctly')
"""Accesability properties/methods"""
@property
def site_codes(self):
return [site.site_info.site_codes for site in self.sites]
@property
def site_names(self):
return [site.site_info.site_name for site in self.sites]
class QueryInfo(XMLParser):
"""
"""
def __init__(self,xml_root,version='wml1.1'):
super(QueryInfo, self).__init__(xml_root,version)
self.parse_query_info()
def parse_query_info(self, xml=None):
if xml is not None:
try:
self._root = etree.parse(xml)
except:
self._root = xml
# try:
# create queryinfo object from dict
xml_dict = _xml_to_dict(self._root)
self.creation_time = parser.parse(xml_dict.get('creation_time')) if xml_dict.get('creation_time') is not None else None
self.notes = [testXMLValue(note) for note in self._findall('note')]
self.criteria = Criteria(self._find('criteria'), self._ns)
# except:
# raise ValueError('Unable to parse queryInfo element correctly')
class Criteria(XMLParser):
"""
"""
def __init__(self,xml_root,version='wml1.1'):
super(Criteria, self).__init__(xml_root,version)
self.parse_criteria()
def parse_criteria(self, xml=None):
if xml is not None:
try:
self._root = etree.parse(xml)
except:
self._root = xml
# try:
xml_dict = _xml_to_dict(self._root,depth=4)
self.method_called = self._root.attrib.get('MethodCalled')
self.location_param = xml_dict.get('location_param')
self.variable_param = xml_dict.get('variable_param')
try:
self.begin_date_time = parser.parse(xml_dict['begin_date_time'])
except:
self.begin_date_time = None
try:
self.end_date_time = parser.parse(xml_dict['end_date_time'])
except:
self.end_date_time = None
self.parameters = [(param.attrib.get('name'),param.attrib.get('value')) for param in self._findall('parameter')]
# except:
# raise ValueError('Unable to parse xml for criteria element')
class Site(XMLParser):
def __init__(self, xml, version='wml1.1'):
super(Site,self).__init__(xml,version)
self.parse_site()
def __iter__(self):
for c in self.series_catalogs:
yield c
def __getitem__(self,key):
if isinstance(key,int) and key < len(self.series_catalogs):
return self.series_catalogs[key]
if isinstance(key,str):
var = [series.variable for catalog in self.series_catalogs for series in catalog if series.code == key]
if len(var) > 0:
return var[0]
raise KeyError('Unknown key ' + str(key))
"""Accessor propeties/methods"""
@property
def name(self):
return self.site_info.site_name
@property
def codes(self):
return self.site_info.site_codes
@property
def variable_names(self):
return list(set([series.variable.variable_name for catalog in self.series_catalogs for series in catalog]))
@property
def variable_codes(self):
return list(set([series.variable.variable_code for catalog in self.series_catalogs for series in catalog]))
@property
def geo_coords(self):
return self.site_info.location.geo_coords
@property
def latitudes(self):
return [g[1] for g in self.site_info.location.geo_coords]
@property
def longitudes(self):
return [g[0] for g in self.site_info.location.geo_coords]
def parse_site(self,xml=None):
if xml is not None:
try:
self._root = etree.parse(xml)
except:
self._root = xml
# try:
self.site_info = SiteInfo(self._find('siteInfo'), self._ns)
self.series_catalogs = [SeriesCatalog(elm, self._ns) for elm in self._findall('seriesCatalog')]
# self.extension = Extension(self._find('extension'), self._ns)
# except:
# raise ValueError('Unable to parse site element correctly')
class SiteInfo(XMLParser):
def __init__(self,xml,version='wml1.1'):
super(SiteInfo,self).__init__(xml,version)
self.parse_siteinfo()
def parse_siteinfo(self,xml=None):
if xml is not None:
try:
self._root = etree.parse(xml)
except:
self._root = xml
# try:
xml_dict = _xml_to_dict(self._root)
self.site_name = xml_dict.get('site_name')
self.site_codes = [testXMLValue(code) for code in self._findall('siteCode')]
self.elevation = xml_dict.get('elevation_m')
self.vertical_datum = xml_dict.get('vertical_datum')
self.site_types = [testXMLValue(typ) for typ in self._findall('siteType')]
self.site_properties = dict([(prop.attrib.get('name'),testXMLValue(prop)) for prop in self._findall('siteProperty')])
self.altname = xml_dict.get('altname')
self.notes = [testXMLValue(note) for note in self._findall('note')]
# sub-objects
tzi = self._find('timeZoneInfo')
if tzi is not None:
self.time_zone_info = TimeZoneInfo(tzi, self._ns)
self.location = Location(self._find('geoLocation'), self._ns)
# except:
# raise ValueError('Unable to parse siteInfo element')
class Location(XMLParser):
def __init__(self,xml,version='wml1.1'):
super(Location,self).__init__(xml,version)
self.parse_location()
def parse_location(self,xml=None):
if xml is not None:
try:
self._root = etree.parse(xml)
except:
self._root = xml
# try:
xml_dict = _xml_to_dict(self._root)
geogs = self._findall('geogLocation')
self.geo_coords = list()
self.srs = list()
for g in geogs:
self.geo_coords.append((testXMLValue(g.find(ns(self._ns) + 'longitude')),testXMLValue(g.find(ns(self._ns) + 'latitude'))))
self.srs.append(g.attrib.get('srs'))
locsite = self._findall('localSiteXY')
self.local_sites = list()
self.notes = list()
self.projections = list()
for ls in locsite:
z = testXMLValue(ls.find(ns(self._ns) + 'Z'))
if z is not None:
self.local_sites.append((testXMLValue(ls.find(ns(self._ns) + 'X')),testXMLValue(ls.find(ns(self._ns) + 'Y')),z))
else:
self.local_sites.append((testXMLValue(ls.find(ns(self._ns) + 'X')),testXMLValue(ls.find(ns(self._ns) + 'Y')),'0'))
self.notes.append([testXMLValue(note) for note in ls.findall(ns(self._ns) + 'note')])
self.projections.append(ls.attrib.get('projectionInformation'))
# except:
# raise ValueError('Unable to parse geoLocation element')
class TimeZoneInfo(XMLParser):
def __init__(self,xml,version='wml1.1'):
super(TimeZoneInfo,self).__init__(xml,version)
self.parse_timezoneinfo()
def parse_timezoneinfo(self,xml=None):
if xml is not None:
try:
self._root = etree.parse(xml)
except:
self._root = xml
# try:
xml_dict = _xml_to_dict(self._root)
default = self._find('defaultTimeZone')
if default is not None:
self.zone_offset = default.attrib.get('zoneOffset')
self.zone_abbreviation = default.attrib.get('zoneAbbreviation')
daylight = self._find('daylightSavingsTimeZone')
if daylight is not None:
self.daylight_zone_offset = daylight.attrib.get('zoneOffset')
self.daylight_zone_abbreviation = daylight.attrib.get('zoneAbbreviation')
# except:
# raise ValueError('Unable to properly parset the timeZoneInfo element')
class SeriesCatalog(XMLParser):
def __init__(self,xml,version='wml1.1'):
super(SeriesCatalog,self).__init__(xml,version)
self.parse_seriescatalog()
def __iter__(self):
for s in self.series:
yield s
def __getitem__(self,key):
if isinstance(key,int) and key < len(self.series):
return self.series[key]
if isinstance(key,str):
srs = [series for series in self.series if series.code == key]
if len(srs) > 0:
return srs[0]
raise KeyError('Unknown key ' + str(key))
def parse_seriescatalog(self,xml=None):
if xml is not None:
try:
self._root = etree.parse(xml)
except:
self._root = xml
# try:
self.series = [Series(elm,self._ns) for elm in self._findall('series')]
# except:
# raise ValueError('Unable to properly parse the seriesCatalog element')
class Series(XMLParser):
def __init__(self,xml,version='wml1.1'):
super(Series,self).__init__(xml,version)
self.parse_series()
"""Accessor proeprties/methods"""
@property
def name(self):
return self.variable.variable_name
@property
def code(self):
return self.variable.variable_code
def parse_series(self,xml=None):
if xml is not None:
try:
self._root = etree.parse(xml)
except:
self._root = xml
# try:
xml_dict = _xml_to_dict(self._root,depth=3)
self.value_count = xml_dict.get('value_count')
self.value_type = xml_dict.get('value_type')
self.general_category = xml_dict.get('general_category')
self.sample_medium = xml_dict.get('sample_medium')
self.data_type = xml_dict.get('data_type')
# date-time
self.begin_date_time = parser.parse(xml_dict.get('begin_date_time'))
self.begin_date_time_utc = parser.parse(xml_dict.get('begin_date_time_utc')) if xml_dict.get('begin_date_time_utc') is not None else None
self.end_date_time = parser.parse(xml_dict.get('end_date_time'))
self.end_date_time_utc = parser.parse(xml_dict.get('end_date_time_utc')) if xml_dict.get('end_date_time_utc') is not None else None
# method info
self.method_description = xml_dict.get('method_description')
self.method_code = xml_dict.get('method_code')
self.method_link = xml_dict.get('method_link')
method = self._find('method')
if method is not None:
self.method_id = method.attrib.get('methodID')
else:
self.method_id = None
# source info
self.organization = xml_dict.get('organization')
self.source_description = xml_dict.get('source_description')
self.citation = xml_dict.get('citation')
source = self._find('source')
if source is not None:
self.source_id = source.attrib.get('sourceID')
else:
self.source_id = None
# quality control info
self.quality_control_level_code = xml_dict.get('quality_control_level_code')
self.definition = xml_dict.get('definition')
qa = self._find('qualityControlLevel')
if qa is not None:
self.quality_control_level_id = qa.attrib.get('qualityControlLevelID')
else:
self.quality_control_level_id = None
# properties
self.properties = dict([(prop.attrib.get('name'),testXMLValue(prop)) for prop in self._findall('seriesProperty')])
# sub-objects
self.variable = Variable(self._find('variable'),self._ns)
# except:
# raise ValueError('Unable to correctly parse Series element')
class Variable(XMLParser):
def __init__(self,xml,version='wml1.1'):
super(Variable,self).__init__(xml,version)
self.parse_variable()
def parse_variable(self,xml=None):
if xml is not None:
try:
self._root = etree.parse(xml)
except:
self._root = xml
# try:
xml_dict = _xml_to_dict(self._root)
self.value_type = xml_dict.get('value_type')
self.data_type = xml_dict.get('data_type')
self.general_category = xml_dict.get('general_category')
self.sample_medium = xml_dict.get('sample_medium')
self.no_data_value = xml_dict.get('no_data_value')
self.variable_name = xml_dict.get('variable_name')
self.variable_code = xml_dict.get('variable_code')
self.variable_description = xml_dict.get('variable_description')
self.speciation = xml_dict.get('speciation')
# notes and properties
notes = [(note.attrib.get('title'),testXMLValue(note)) for note in self._findall('note')]
none_notes = [note[1] for note in notes if note[0] is None]
self.notes = dict([note for note in notes if note[0] is not None])
if len(none_notes) > 0:
self.notes['none'] = none_notes
self.properties = dict([(prop.attrib.get('name'),testXMLValue(prop)) for prop in self._findall('variableProperty')])
# related
related = self._find('related')
if related is not None:
self.parent_codes = [dict([('network',code.attrib.get('network')),('vocabulary',code.attrib.get('vocabulary')),('default',code.attrib.get('default'))])
for code in related.findall(ns(self._ns) + 'parentCode')]
self.related_codes = [dict([('network',d.get('network')),('vocabulary',d.get('vocabulary')),('default',d.get('default'))])
for code in related.findall(ns(self._ns) + 'relatedCode')]
else:
self.parent_codes = None
self.related_codes = None
# sub-objects
if self._ns == 'wml1.0':
unit = self._find('units')
self.unit = Unit1_0(unit, self._ns) if unit is not None else None
timesupport = self._find('timeSupport')
self.time_support = TimeScale(timesupport, self._ns) if timesupport is not None else None
else:
unit = self._find('unit')
self.unit = Unit(unit, self._ns) if unit is not None else None
timescale = self._find('timeScale')
self.time_scale = TimeScale(timescale, self._ns) if timescale is not None else None
categories = self._find('categories')
if categories is not None:
self.categories = [Category(cat,self._ns) for cat in categories.findall(ns(self._ns) + 'category')]
else:
self.categories = None
# except:
# raise ValueError('Unable to correctly parse variable element')
class TimeScale(XMLParser):
def __init__(self,xml,version='wml1.1'):
super(TimeScale,self).__init__(xml,version)
self.parse_timescale()
def parse_timescale(self):
try:
xml_dict = _xml_to_dict(self._root)
self.time_spacing = xml_dict.get('time_spacing')
self.time_support = xml_dict.get('time_support')
self.time_interval = xml_dict.get('time_interval')
unit = self._find('unit')
self.unit = Unit(unit, self._ns) if unit is not None else None
except:
raise
class Unit(XMLParser):
def __init__(self,xml,version='wml1.1'):
super(Unit,self).__init__(xml,version)
self.parse_unit()
def parse_unit(self):
try:
xml_dict = _xml_to_dict(self._root)
self.name = xml_dict.get('unit_name')
self.unit_type = xml_dict.get('unit_type')
self.description = xml_dict.get('unit_description')
self.abbreviation = xml_dict.get('unit_abbreviation')
self.code = xml_dict.get('unit_code')
self.id = self._root.attrib.get('UnitID')
except:
raise
class Unit1_0(XMLParser):
def __init__(self,xml,version='wml1.0'):
super(Unit1_0,self).__init__(xml,version)
self.parse_unit()
def parse_unit(self):
try:
self.name = testXMLValue(self._root)
self.code = self._root.attrib.get('unitsCode')
self.abbreviation = self._root.attrib.get('unitsAbbreviation')
self.type = self._root.attrib.get('unitsType')
self.id = self._root.attrib.get('unitID')
except:
raise
class Category(XMLParser):
def __init__(self,xml,version='wml1.1'):
super(Category,self).__init__(xml,version)
self.parse_category()
def parse_category(self):
try:
xml_dict = _xml_to_dict(self._root)
self.data_value = xml_dict.get('data_value')
self.description = xml_dict.get('description')
self.id = self._root.attrib.get('categoryID')
except:
raise
class TimeSeriesResponse(XMLParser):
"""
Parses the response from a 'GetValues' request
Parameters
===========
:xmlio - A file-like object that holds the xml response from the request.
Return
=======
An object constructed from a dictionary parse of the response. The object has get access and can
also iterate over each timeSeries element returned.
"""
def __init__(self,xml,version='wml1.1'):
super(TimeSeriesResponse,self).__init__(xml,version)
self.parse_timeseriesresponse()
"""Accessor properties/methods"""
@property
def series_names(self):
return [series.name for series in self.time_series]
@property
def variable_names(self):
return list(set([series.variable.variable_name for series in self.time_series]))
@property
def variable_codes(self):
return list(set([s.variable.variable_code for s in self.time_series]))
def get_series_by_variable(self,var_name=None,var_code=None):
if var_code is not None:
return [s for s in self.time_series if s.variable.variable_code == var_code]
elif var_name is not None:
return [series for series in self.time_series if series.variable.variable_name == var_name]
return None
def parse_timeseriesresponse(self):
try:
qi = self._find('queryInfo')
self.query_info = QueryInfo(qi,self._ns)
self.time_series = [TimeSeries(series,self._ns) for series in self._findall('timeSeries')]
except:
raise
class TimeSeries(XMLParser):
def __init__(self,xml,version='wml1.1'):
super(TimeSeries,self).__init__(xml,version)
self.parse_timeseries()
def parse_timeseries(self):
try:
self.variable = Variable(self._find('variable'), self._ns)
self.values = [Values(val,self._ns) for val in self._findall('values')]
self.source_info = SiteInfo(self._find('sourceInfo'), self._ns)
self.name = self._root.attrib.get('name')
except:
raise
class Values(XMLParser):
def __init__(self,xml,version='wml1.1'):
super(Values,self).__init__(xml,version)
self.parse_values()
def __iter__(self):
for v in self.values:
yield v
"""Accessor properties/methods"""
def get_date_values(self,method_id=None,source_id=None,sample_id=None,quality_level=None,utc=False):
varl = [v for v in self.values]
if method_id is not None:
varl = [v for v in varl if v.method_id == method_id]
if source_id is not None:
varl = [v for v in varl if v.source_id == source_id]
if sample_id is not None:
varl = [v for v in varl if v.sample_id == sample_id]
if quality_level is not None:
varl = [v for v in varl if v.quality_control_level == quality_level]
if not utc:
return [(v.date_time,v.value) for v in varl]
else:
return [(v.date_time_utc,v.value) for v in varl]
def parse_values(self):
xml_dict = _xml_to_dict(self._root)
# method info
self.methods = [Method(method,self._ns) for method in self._findall('method')]
# source info
self.sources = [Source(source,self._ns) for source in self._findall('source')]
# quality control info
self.qualit_control_levels = [QualityControlLevel(qal, self._ns) for qal in self._findall('qualityControlLevel')]
# offset info
self.offsets = [Offset(os,self._ns) for os in self._findall('offset')]
# sample info
self.samples = [Sample(sample,self._ns) for sample in self._findall('sample')]
# censor codes
self.censor_codes = [CensorCode(code, self._ns) for code in self._findall('censorCode')]
# unit
if self._ns == 'wml1.0':
self.unit_abbreviation = self._root.attrib.get('unitsAbbreviation')
self.unit_code = self._root.attrib.get('unitsCode')
self.count = self._root.attrib.get('count')
else:
unit = self._find('unit')
self.unit = Unit(unit, self._ns) if unit is not None else None
# values
self.values = [Value(val, self._ns) for val in self._findall('value')]
class Value(XMLParser):
def __init__(self,xml,version='wml1.1'):
super(Value,self).__init__(xml,version)
self.parse_value()
def parse_value(self):
try:
self.value = testXMLValue(self._root)
d = self._root.attrib
self.qualifiers = d.get('qualifiers')
self.censor_code = d.get('censorCode')
self.date_time = parser.parse(d.get('dateTime')) if d.get('dateTime') is not None else None
self.time_offset = d.get('timeOffset')
self.date_time_utc = parser.parse(d.get('dateTimeUTC')) if d.get('dateTimeUTC') is not None else None
self.method_id = d.get('methodID')
self.source_id = d.get('sourceID')
self.accuracy_std_dev = d.get('accuracyStdDev')
self.sample_id = d.get('sampleID')
self.method_code = d.get('methodCode')
self.source_code = d.get('sourceCode')
self.lab_sample_code = d.get('lab_sample_code')
self.offset_value = d.get('offsetValue')
self.offset_type_id = d.get('offsetTypeID')
self.offset_type_code = d.get('offsetTypeCode')
self.coded_vocabulary = d.get('codedVocabulary')
self.coded_vocabulary_term = d.get('codedVocabularyTerm')
self.quality_control_level = d.get('qualityControlLevel')
self.metadata_time = d.get('metadataTime')
self.oid = d.get('oid')
except:
raise
class Sample(XMLParser):
def __init__(self,xml,version='wml1.1'):
super(Sample,self).__init__(xml,version)
self.parse_sample()
def parse_sample(self):
try:
xml_dict = _xml_to_dict(self._root)
self.code = xml_dict.get('lab_sample_code')
self.type = xml_dict.get('sample_type')
lm = self._find('labMethod')
self.method = LabMethod(lm, self._ns) if lm is not None else None
except:
raise
class LabMethod(XMLParser):
def __init__(self,xml,version='wml1.1'):
super(LabMethod,self).__init__(xml,version)
self.parse_labmethod()
def parse_labmethod(self):
try:
xml_dict = _xml_to_dict(self._root)
self.code = xml_dict.get('lab_code')
self.name = xml_dict.get('lab_name')
self.organization = xml_dict.get('lab_organization')
self.method_name = xml_dict.get('lab_method_name')
self.method_description = xml_dict.get('lab_method_description')
self.method_link = xml_dict.get('lab_method_link')
# sub-objects
source = self._find('labSourceDetails')
self.source_details = Source(source,self._ns) if source is not None else None
except:
raise
class Source(XMLParser):
def __init__(self,xml,version='wml1.1'):
super(Source,self).__init__(xml,version)
self.parse_source()
def __str__(self):
return str(self.__dict__)
def get_contact(self,name):
ci = [ci for ci in self.contact_info if ci.name == name]
if len(ci) < 0:
return ci[0]
return None
def parse_source(self):
try:
xml_dict = _xml_to_dict(self._root)
self.code = xml_dict.get('source_code')
self.organization = xml_dict.get('organization')
self.description = xml_dict.get('source_description')
self.links = [testXMLValue(link) for link in self._findall('sourceLink')]
self.citation = xml_dict.get('citation')
# metadata
self.topic_category = xml_dict.get('topic_category')
self.title = xml_dict.get('title')
self.abstract = xml_dict.get('abstract')
self.profile_version = xml_dict.get('profile_version')
self.metadata_link = xml_dict.get('metadata_link')
# contact info
self.contact_info = [ContactInformation(ci,self._ns) for ci in self._findall('contactInformation')]
except:
raise
class ContactInformation(XMLParser):
def __init__(self,xml,version='wml1.1'):
super(ContactInformation,self).__init__(xml,version)
self.parse_contactinformation()
def parse_contactinformation(self):
try:
xml_dict = _xml_to_dict(self._root)
self.name = xml_dict.get('contact_name')
self.type = xml_dict.get('type_of_contact')
self.email = [testXMLValue(email) for email in self._findall('email')]
self.phone = [testXMLValue(phone) for phone in self._findall('phone')]
self.address = [testXMLValue(address) for address in self._findall('address')]
except:
raise
class Offset(XMLParser):
def __init__(self,xml,version='wml1.1'):
super(Offset,self).__init__(xml,version)
self.parse_offset()
def parse_offset(self):
try:
xml_dict = _xml_to_dict(self._root)
self.type_code = xml_dict.get('offset_type_code')
self.value = xml_dict.get('offset_value')
self.description = xml_dict.get('offset_description')
self.is_vertical = xml_dict.get('offset_is_vertical')
self.azimuth_degrees = xml_dict.get('offset_azimuth_degrees')
unit = self._root.find('unit')
if self._ns == 'wml1.0':
self.unit = Unit1_0(unit, self._ns) if unit is not None else None
else:
self.unit = Unit(unit,self._ns) if unit is not None else None
except:
raise
class Method(XMLParser):
def __init__(self,xml,version='wml1.1'):
super(Method,self).__init__(xml,version)
self.parse_method()
def parse_method(self):
try:
xml_dict = _xml_to_dict(self._root)
self.code = xml_dict.get('method_code')
self.description = xml_dict.get('method_description')
self.link = xml_dict.get('method_link')
self.id = self._root.attrib.get('methodID')
except:
raise
class QualityControlLevel(XMLParser):
def __init__(self,xml,version='wml1.1'):
super(QualityControlLevel,self).__init__(xml,version)
self.parse_qcl()
def parse_qcl(self):
try:
xml_dict = _xml_to_dict(self._root)
self.code = xml_dict.get('quality_control_level_code')
self.definition = xml_dict.get('definition')
self.explanation = xml_dict.get('explanation')
self.id = self._root.attrib.get('qualityControlLevelID')
except:
raise
class CensorCode(XMLParser):
def __init__(self,xml,version='wml1.1'):
super(CensorCode,self).__init__(xml,version)
self.parse_censorcode()
def parse_censorcode(self):
try:
xml_dict = _xml_to_dict(self._root)
self.code = xml_dict.get('censor_code')
self.description = xml_dict.get('censor_code_description')
self.id = self._root.attrib.get('censorCodeID')
except:
raise
class VariablesResponse(XMLParser):
"""
Parses the response from a 'GetVariableInfo' request
Parameters
===========
:xmlio - A file-like object that holds the xml response from the request.
Return
=======
An object constructed from a dictionary parse of the response. The object has get access to its variables and
can also be used as an iterator.
"""
def __init__(self,xml,version='wml1.1'):
super(VariablesResponse,self).__init__(xml,version)
self.parse_variablesresponse()
def __iter__(self):
for v in self.variables:
yield v
def __getitem__(self,key):
if isinstance(key,int) and key < len(self.variables):
return self.variables[key]
if isinstance(key,str):
v = [var for var in self.variables if var.variable_code == key]
if len(v) > 0:
return v[0]
v = [var for var in self.variables if var.variable_name == key]
if len(v) > 0:
return v[0]
raise KeyError('Unknown key ' + str(key))
"""Accessor properties/methods"""
@property
def variable_names(self):
return list(set([var.variable_name for var in self.variables]))
@property
def variable_codes(self):
return [var.variable_code for var in self.variables]
def parse_variablesresponse(self):
try:
qi = self._find('queryInfo')
self.query_info = QueryInfo(qi, self._ns) if qi is not None else None
varis = self._find('variables')
self.variables = [Variable(var,self._ns) for var in varis.findall(ns(self._ns) + 'variable')]
except:
raise