def check(self): name_contest_id = {} # Mapping for <Name> and its Contest ObjectId. error_log = [] for event, element in etree.iterwalk(self.election_tree): tag = self.strip_schema_ns(element) if tag != "Contest": continue object_id = element.get("objectId", None) name = element.find("Name") if name is None or not name.text: error_message = "Contest {0} is missing a <Name> ".format( object_id) error_log.append(base.ErrorLogEntry( element.sourceline, error_message)) continue name_contest_id.setdefault(name.text, []).append(object_id) """Add names and its objectId as key and list of values. Ideally 1 objectId. If duplicates are found, then list of multiple objectIds.""" for name, contests in name_contest_id.items(): if len(contests) > 1: error_message = ("Contest name '{0}' appears in following {1} contests: {2}".format( name, len(contests), ", ".join(contests))) error_log.append(base.ErrorLogEntry(None, error_message)) if error_log: raise base.ElectionTreeError( "The Election File contains duplicate contest names.", error_log)
def check(self): error_log = [] candidates = self.get_elements_by_class(self.election_tree, "Candidate") for candidate in candidates: cand_id = candidate.get("objectId", None) self.cand_to_cand_selection[cand_id] = [] candidate_selections = self.get_elements_by_class( self.election_tree, "CandidateSelection") for candidate_selection in candidate_selections: candidate_selection_id = candidate_selection.get("objectId", None) candidate_ids = candidate_selection.find("CandidateIds") if candidate_ids is None or candidate_selection_id is None: break for candidate_id in candidate_ids.text.split(): self.cand_to_cand_selection.setdefault( candidate_id, []).append(candidate_selection_id) for cand_id, cand_select_ids in self.cand_to_cand_selection.items(): if len(cand_select_ids) == 0: error_message = "A Candidate object should be referenced from one" \ " CandidateSelection. Candidate {0} is not referenced by any" \ " CandidateSelections".format(cand_id) error_log.append(base.ErrorLogEntry( None, error_message)) if error_log: raise base.ElectionTreeError( "The Election File contains unreferenced Candidates", error_log)
def check(self): identifier_values = {} error_log = [] nist_objects = ("Candidate", "Contest", "Party") for event, element in etree.iterwalk(self.election_tree): nist_obj = self.strip_schema_ns(element) if nist_obj not in nist_objects: continue object_id = element.get("objectId") external_identifiers = element.find("ExternalIdentifiers") if external_identifiers is None: error_message = "{0} {1} is missing a stable ExternalIdentifier".format( nist_obj, object_id) error_log.append( base.ErrorLogEntry(element.sourceline, error_message)) continue identifier = external_identifiers.find("ExternalIdentifier") if identifier is None: error_message = "{0} {1} is missing a stable ExternalIdentifier".format( nist_obj, object_id) error_log.append( base.ErrorLogEntry(element.sourceline, error_message)) continue value = identifier.find("Value") if value is None or not value.text: error_message = "{0} {1} is missing a stable ExternalIdentifier".format( nist_obj, object_id) error_log.append( base.ErrorLogEntry(element.sourceline, error_message)) continue identifier_values.setdefault(value.text, []).append(object_id) for value_text, obj_ids in identifier_values.items(): if len(obj_ids) > 1: error_message = "Stable ExternalIdentifier '{0}' is a used for following {1} objectIds: {2}".format( value_text, len(obj_ids), ", ".join(obj_ids)) error_log.append(base.ErrorLogEntry(None, error_message)) if error_log: raise base.ElectionTreeError( "The Election File has following issues with the identifiers.", error_log)
def check(self): for event, element in etree.iterwalk( self.election_tree): if element.tag not in self.NIST_objects: continue else: NIST_obj=element.tag object_id=element.get('objectId') ExternalIdentifiers=element.find("ExternalIdentifiers") if ExternalIdentifiers is None: error_message="Missing <ExternalIdentifiers> tag/block in {0} with ID {1}.".format(NIST_obj,object_id) self.error_log.append(base.ErrorLogEntry( element.sourceline, error_message)) else: Identifier=ExternalIdentifiers.find("ExternalIdentifier") if Identifier is None: error_message="Missing <ExternalIdentifier> tag/block in {0} with ID {1}.".format(NIST_obj,object_id) self.error_log.append(base.ErrorLogEntry(ExternalIdentifiers.sourceline, error_message)) else: Type=Identifier.find("Type") OtherType=Identifier.find("OtherType") Value=Identifier.find("Value") if Value is None or Value.text is None: error_message="Missing <Value> tag/block and its value in {0} with ID {1}".format(NIST_obj,object_id) self.error_log.append(base.ErrorLogEntry(Identifier.sourceline, error_message)) else: if Value.text != object_id: error_message="{0} ObjectId and <Value> {1} Mismatched. Should be same in {2}.".format(object_id,Value.text,NIST_obj) self.error_log.append(base.ErrorLogEntry(Value.sourceline, error_message)) self.identifier_values.setdefault(Value.text,[]).append(Value.sourceline) for _id,_lines in self.identifier_values.iteritems(): if(len(_lines)>1): for line in _lines: error_message="'{0}' is a duplicate Identifier Value".format(_id) self.error_log.append(base.ErrorLogEntry(line, error_message)) if self.error_log: raise base.ElectionTreeError( "The Election File contains duplicate contest names.", self.error_log)
def check(self): for event, element in etree.iterwalk( self.election_tree): if(element.tag!='Contest'): continue else: name=element.find("Name") if name.text is not None and name.text!="": self.names_lines.setdefault(name.text,[]).append(name.sourceline) for _name,_lines in self.names_lines.iteritems(): if(len(_lines)>1): for line in _lines: error_message="'{0}' is a duplicate contest name".format(_name) self.error_log.append(base.ErrorLogEntry(line, error_message)) if self.error_log: raise base.ElectionTreeError( "The Election File contains duplicate contest names.", self.error_log)
def check(self): schema_tree = etree.parse(self.schema_file) try: schema = etree.XMLSchema(etree=schema_tree) except etree.XMLSchemaParseError as e: raise base.ElectionError( "The schema file could not be parsed correctly %s" % str(e)) valid_xml = True try: schema.assertValid(self.election_tree) except etree.DocumentInvalid as e: valid_xml = False if not valid_xml: errors = [] for error in schema.error_log: errors.append( base.ErrorLogEntry(error.line, error.message.encode("utf-8"))) raise base.ElectionTreeError( "The election file didn't validate against schema.", errors)
def check(self): all_object_ids = set() error_log = [] for event, element in etree.iterwalk( self.election_tree, events=("end",)): if "objectId" not in element.attrib: continue else: obj_id = element.get("objectId") if not obj_id: continue if obj_id in all_object_ids: error_line = element.sourceline error_message = "{0} is a duplicate object ID".format( obj_id) error_log.append(base.ErrorLogEntry( error_line, error_message)) else: all_object_ids.add(obj_id) if error_log: raise base.ElectionTreeError( "The Election File contains duplicate object IDs", error_log)
def check(self): error_log = [] candidate_selections = self.get_elements_by_class( self.election_tree, "CandidateSelection") for candidate_selection in candidate_selections: candidate_selection_id = candidate_selection.get("objectId", None) candidate_ids = candidate_selection.find("CandidateIds") if candidate_ids is None: break for candidate_id in candidate_ids.text.split(): if candidate_selection_id: self.seen_candidates.setdefault( candidate_id, []).append(candidate_selection_id) for cand_id, cand_select_ids in self.seen_candidates.items(): if len(cand_select_ids) > 1: error_message = "A Candidate object should only ever be " \ "referenced from one CandidateSelection. Candidate %s is " \ "referenced by the following CandidateSelections :- %s" % ( cand_id, ", ".join(cand_select_ids)) error_log.append(base.ErrorLogEntry(None, error_message)) if error_log: raise base.ElectionTreeError( "The Election File contains reused Candidates", error_log)