diff --git a/pythonedi/EDIGenerator.py b/pythonedi/EDIGenerator.py index e195b95..2ba2029 100644 --- a/pythonedi/EDIGenerator.py +++ b/pythonedi/EDIGenerator.py @@ -80,11 +80,11 @@ def build_segment(self, segment, segment_data): output_elements = [segment["id"]] for e_data, e_format, index in zip(segment_data, segment["elements"], range(len(segment["elements"]))): output_elements.append(self.build_element(e_format, e_data)) - + # End of segment. If segment has syntax rules, validate them. if "syntax" in segment: for rule in segment["syntax"]: - # Note that the criteria indexes are one-based + # Note that the criteria indexes are one-based # rather than zero-based. However, the output_elements # array is prepopulated with the segment name, # so the net offset works perfectly! @@ -127,7 +127,7 @@ def build_segment(self, segment, segment_data): required_elements = ", ".join(["{}{:02d}".format(segment["id"], e) for e in rule["criteria"][0]]) Debug.explain(segment) raise ValueError("Syntax error parsing segment {}: If {} is present, at least one of {} are required.".format(segment["id"], first_element, required_elements)) - + return self.element_delimiter.join(output_elements) def build_element(self, e_format, e_data): @@ -139,7 +139,7 @@ def build_element(self, e_format, e_data): elif e_format["req"] == "O": return "" else: - raise ValueError("Unknown 'req' value '{}' when processing format for element '{}' in set '{}'".format(e_format["req"], element_id, ts_id)) + raise ValueError("Unknown 'req' value '{}' when processing format for element '{}' in set '{}'".format(e_format["req"], element_id)) try: if e_format["data_type"] == "AN": formatted_element = str(e_data) @@ -176,11 +176,11 @@ def build_element(self, e_format, e_data): else: raise ValueError("Undefined behavior for empty data type with element '{}'".format(element_id)) except: - raise ValueError("Error converting '{}' to data type '{}'".format(e_data, e_format["data_type"])) + raise ValueError("Error converting '{}' to data type '{}' for '{}'".format(e_data, e_format["data_type"], element_id)) # Pad/trim formatted element to fit the field min/max length respectively formatted_element += " "*(e_format["length"]["min"]-len(formatted_element)) formatted_element = formatted_element[:e_format["length"]["max"]] # Add element to list - return formatted_element \ No newline at end of file + return formatted_element diff --git a/pythonedi/EDIParser.py b/pythonedi/EDIParser.py index c88fa36..05ae8c8 100644 --- a/pythonedi/EDIParser.py +++ b/pythonedi/EDIParser.py @@ -37,7 +37,7 @@ def parse(self, data): to_return = {} found_segments = [] - + while len(edi_segments) > 0: segment = edi_segments[0] if segment == "": @@ -63,14 +63,17 @@ def parse(self, data): segment_name = seg_format["id"] segment_obj, edi_segments = self.parse_loop(edi_segments, seg_format) break - + if segment_obj is None: Debug.log_error("Unrecognized segment: {}".format(segment)) edi_segments = edi_segments[1:] # Skipping segment continue # raise ValueError - found_segments.append(segment_name) + if (segment_name in to_return) and (isinstance(to_return[segment_name], list)): + to_return[segment_name].extend(segment_obj) + else: + to_return[segment_name] = segment_obj to_return[segment_name] = segment_obj @@ -156,7 +159,7 @@ def parse_loop(self, edi_segments, loop_format): if segment_obj is None: # Reached the end of valid segments; return what we have break - elif segment_name == loop_format["segments"][0]["id"] and loop_dict != {}: + elif segment_name == loop_format["segments"][0]["id"] and loop_dict != {}: # Beginning a new loop, tie off this one and start fresh loop_list.append(loop_dict.copy()) loop_dict = {} diff --git a/pythonedi/supported_formats.py b/pythonedi/supported_formats.py index 17e5b39..a119445 100644 --- a/pythonedi/supported_formats.py +++ b/pythonedi/supported_formats.py @@ -5,13 +5,19 @@ import os import json + def load_supported_formats(formats_path): supported_formats = {} for filename in os.listdir(formats_path): if filename.endswith(".json"): format_name = filename[:-5] with open(os.path.join(formats_path, filename)) as format_file: - format_def = json.load(format_file) + try: + format_def = json.load(format_file) + except json.decoder.JSONDecodeError as e: + raise SyntaxError( + f"Failed to parse format: {format_name}\r\nError: {e}" + ) if type(format_def) is not list: raise TypeError("Imported definition {} is not a list of segments".format(format_name)) supported_formats[format_name] = format_def