def validate(self, tree): logger.info('Validating file "%s"...' % self.filename) validation = True if LXML: dtdfile = os.path.join(os.path.dirname(__file__), 'cnml.dtd') try: with open(dtdfile, 'rb') as dtdfp: dtd = etree.DTD(dtdfp) logger.info('DTD validation: %s' % dtd.validate(tree)) errors = dtd.error_log.filter_from_errors() if len(errors) > 0: logger.warning('%d errors found:' % len(errors)) logger.warning(errors) validation = False except IOError: logger.error('DTD Validation failed: %s file not found' % dtdfile) validation = False else: logger.warn('DTD validation is not implemented with Minidom API') validation = False return validation
def validateDTDLxml(self, tree): validation = True dtdfile = os.path.join(os.path.dirname(__file__), 'cnml.dtd') try: with open(dtdfile, 'rb') as dtdfp: dtd = etree.DTD(dtdfp) logger.info('DTD validation: %s' % dtd.validate(tree)) errors = dtd.error_log.filter_from_errors() if len(errors) > 0: logger.warning('%d errors found:' % len(errors)) logger.warning(errors) validation = False except IOError: logger.error('DTD Validation failed: %s file not found' % dtdfile) validation = False return validation
def load(self, validate=True): self.zones = dict() self.nodes = dict() self.devices = dict() self.services = dict() self.radios = dict() self.ifaces = dict() self.links = dict() self.innerlinks = {} self.outerlinks = {} self.url_contents = None # if URL has been passed, get the contents if isinstance(self.filename, six.string_types) and self.filename.startswith('http'): self.url_contents = request.urlopen(self.filename).read() # decode response if needed if not isinstance(self.url_contents, six.string_types): self.url_contents = self.url_contents.decode() if LXML: loaded = self._loadLxml(validate=validate) else: try: loaded = self._loadMinidom(validate=validate) except: loaded = False if loaded: logger.info('Loaded "%s" successfully' % self.filename) # Replace None by true reference of nodes/devices/interfaces # Note that if they belong to a different zone they might not be defined in the CNML file for link in self.get_links(): link._set_linked_parameters(self.devices, self.ifaces, self.nodes) if isinstance(link.nodeA, CNMLNode) and isinstance(link.nodeB, CNMLNode): # inner self.innerlinks[link.id] = link else: self.outerlinks[link.id] = link else: logger.error('There were some errors loading "%s"' % self.filename) self.loaded = loaded return loaded
def _loadLxml(self, validate=True): try: if not self.url_contents: tree = etree.parse(self.filename) else: tree = etree.fromstring(self.url_contents) except XMLSyntaxError as e: logger.error('Error reading CNML file: %s' % e) logger.error('The file might be corrupted.') return False if validate: logger.info('Validating file "%s"...' % self.filename) if not self.validate(tree): return False self._get_cnml_type(tree) add_zones = self.cnml_type == 'detail' if add_zones: self._parse_zones(tree) self._parse_nodes(tree, add_zones=add_zones) return True
def loadLxml(self, validate=True): try: if not self.url_contents: tree = etree.parse(self.filename) else: tree = etree.fromstring(self.url_contents) except XMLSyntaxError as e: logger.error('Error reading CNML file: %s' % e) logger.error('The file might be corrupted. Please remove it manually:') logger.error('rm %s' % self.filename) return False if validate: logger.info('Validating file "%s"...' % self.filename) if not self.validateDTDLxml(tree): return False # --zones-- zones = tree.iterfind('.//zone') # Save root zone id self.rootzone = int(tree.find('.//zone[1]').get('id')) for z in zones: zid = int(z.get('id')) newzone = CNMLZone.parse(z) self.zones[zid] = newzone zparentid = newzone.parentzone if zid != self.rootzone and zparentid is not None: self.zones[zparentid].addSubzone(newzone) # --nodes-- for n in tree.iterfind('.//node'): nid = int(n.get('id')) zid = int(n.getparent().get('id')) newnode = CNMLNode.parse(n) self.nodes[nid] = newnode self.zones[zid].addNode(newnode) #assert n.parentNode.localName == u'zone' #assert(ndevices == len(devicestree)) # --devices-- for d in n.iterfind('device'): did = int(d.get('id')) newdevice = CNMLDevice.parse(d, newnode) self.devices[did] = newdevice self.nodes[nid].addDevice(newdevice) # --interfaces-- # If there's a working service in this device, it has interfaces (and it's not a son of a radio!) for i in d.iterchildren('interface'): iid = int(i.get('id')) newiface = CNMLInterface.parse(i, newdevice) self.ifaces[iid] = newiface self.devices[did].addInterface(newiface) # --links-- for l in i.iterfind('link'): lid = int(l.get('id')) if lid in self.links: self.links[lid].parseLinkB(l) self.ifaces[iid].addLink(self.links[lid]) else: newlink = CNMLLink.parse(l, newiface) self.links[lid] = newlink self.ifaces[iid].addLink(newlink) # --services-- for s in d.iterfind('service'): sid = int(s.get('id')) newservice = CNMLService.parse(s, newdevice) self.services[sid] = newservice self.nodes[nid].addService(newservice) # --radios-- for r in d.iterfind('radio'): rid = int(r.get('id')) newradio = CNMLRadio.parse(r, newdevice) self.radios[(did, rid)] = newradio self.devices[did].addRadio(newradio) # --interfaces-- for i in r.iterfind('interface'): iid = int(i.get('id')) newiface = CNMLInterface.parse(i, newradio) self.ifaces[iid] = newiface self.devices[did].radios[rid].addInterface(newiface) # --links-- for l in i.iterfind('link'): lid = int(l.get('id')) if lid in self.links: self.links[lid].parseLinkB(l) self.ifaces[iid].addLink(self.links[lid]) else: newlink = CNMLLink.parse(l, newiface) self.links[lid] = newlink self.ifaces[iid].addLink(newlink) return True