def get_first_matching_segment(self, x12_path_str): """ Get first found Segment at the given relative path. If the path is not a valid relative path or if the given segment index does not exist, the function returns None. @param x12_path_str: Relative X12 Path @type x12_path_str: string @return: First matching data segment @rtype: L{node<segment.Segment>} @raise X12PathError: On blank or invalid path """ (curr, new_path_str) = self._get_start_node(x12_path_str) xpath = path.X12Path(new_path_str) if len(xpath.loop_list) != 0: raise errors.X12PathError( 'This X12 Path should not contain loops: %s' % (x12_path_str)) seg_id = xpath.seg_id qual = xpath.id_val ele_idx = xpath.ele_idx if ele_idx is not None and seg_id is None: return self.seg_data #subele_idx = xpath.subele_idx try: if curr.x12_map_node.is_match_qual(curr.seg_data, seg_id, qual): return curr.seg_data return None except errors.EngineError as e: raise errors.X12PathError( 'X12 Path is invalid or was not found: %s' % (x12_path_str)) return None
def get_first_matching_segment(self, x12_path_str): """ Get first found Segment at the given relative path. If the path is not a valid relative path or if the given segment index does not exist, the function returns None. @param x12_path_str: Relative X12 Path @type x12_path_str: string @return: First matching data segment @rtype: L{node<segment.Segment>} @raise X12PathError: On blank or invalid path """ if len(x12_path_str) == 0: raise errors.X12PathError('Blank X12 Path') (curr, new_path) = self._get_start_node(x12_path_str) xpath = path.X12Path(new_path) if xpath.seg_id is None: return None if len(xpath.loop_list) == 0: seg_id = xpath.seg_id qual = xpath.id_val try: for seg in [seg for seg in curr.children if seg.type == 'seg']: if seg.x12_map_node.is_match_qual(seg.seg_data, seg_id, qual): return seg.seg_data return None except errors.EngineError as e: raise errors.X12PathError( 'X12 Path is invalid or was not found: %s' % (x12_path_str)) else: next_id = xpath.loop_list[0] del xpath.loop_list[0] try: for loop in [ loop for loop in curr.children if loop.type == 'loop' ]: if loop.id == next_id: return loop.get_first_matching_segment(xpath.format()) return None except errors.EngineError as e: raise errors.X12PathError( 'X12 Path is invalid or was not found: %s' % (x12_path_str))
def _get_start_node(self, x12_path_str): """ Move up the tree. Get the new starting node and the altered path """ curr = self while x12_path_str[:3] == '../': if curr.parent is None: raise errors.X12PathError( 'Current node %s does not have a parent: %s' % (self.id, x12_path_str)) curr = curr.parent x12_path_str = x12_path_str[3:] return (curr, x12_path_str)
def set_value(self, x12_path_str, val): """ Set the value of simple element at the first found segment at the given path @param x12_path_str: Relative X12 Path @type x12_path_str: string @param val: The new element value @type val: string """ seg_data = self.get_first_matching_segment(x12_path_str) if seg_data is None: raise errors.X12PathError( 'X12 Path is invalid or was not found: %s' % (x12_path_str)) #ele_idx = self.get_ele_idx(x12_path_str) #seg_data.set(ele_idx, val) seg_data.set(x12_path_str, val)
def add_node(self, data_node): """ Add a X12DataNode instance The x12_map_node of the given data_node must be a direct child of this object's x12_map_node @param data_node: The child loop node to add @type data_node : L{node<x12context.X12DataNode>} @raise errors.X12PathError: On blank or invalid path """ if data_node.x12_map_node.parent != self.x12_map_node: raise errors.X12PathError( 'The loop_data_node "%s" is not a child of "%s"' % (data_node.x12_map_node.id, self.x12_map_node.id)) data_node.parent = self child_idx = self._get_insert_idx(data_node.x12_map_node) self.children.insert(child_idx, data_node)
def set_value(self, x12_path_str, val): """ Set the value of simple element at the first found segment at the given path @param x12_path_str: Relative X12 Path @type x12_path_str: string @param val: The new element value @type val: string """ (curr, new_path) = self._get_start_node(x12_path_str) seg_data = curr.get_first_matching_segment(new_path) if seg_data is None: raise errors.X12PathError( 'X12 Path is invalid or was not found: %s' % (x12_path_str)) xpath = path.X12Path(new_path) xpath.loop_list = [] xpath.id_val = None seg_part = xpath.format() seg_data.set(seg_part, val)
def add_loop(self, seg_data): """ Add a new loop in the correct location @param seg_data: Segment data @type seg_data: L{node<segment.Segment>} or string @return: New loop_data_node, or None if failed @rtype: L{node<x12context.X12LoopDataNode>} """ seg_data = self._get_segment(seg_data) x12_loop_node = self.x12_map_node.get_child_loop_node(seg_data) if x12_loop_node is None: raise errors.X12PathError( 'The segment %s is not a member of loop %s' % (seg_data.__repr__(), self.id)) new_data_loop = self._add_loop_node(x12_loop_node) # Now, add the segment x12_seg_node = new_data_loop.x12_map_node.get_child_seg_node(seg_data) new_data_node = X12SegmentDataNode(x12_seg_node, seg_data, new_data_loop) new_data_loop.add_node(new_data_node) return new_data_loop
def add_segment(self, seg_data): """ Add the segment to this loop node iif the segment is the anchor for a child loop, also adds the loop @param seg_data: Segment data @type seg_data: L{node<segment.Segment>} or string @return: New segment, or None if failed @rtype: L{node<x12context.X12SegmentDataNode>} @raise pyx12.errors.X12PathError: If invalid segment @todo: Check counts? """ seg_data = self._get_segment(seg_data) x12_seg_node = self.x12_map_node.get_child_seg_node(seg_data) if x12_seg_node is None: raise errors.X12PathError( 'The segment %s is not a member of loop %s' % (seg_data.__repr__(), self.id)) new_data_node = X12SegmentDataNode(x12_seg_node, seg_data, self) child_idx = self._get_insert_idx(x12_seg_node) self.children.insert(child_idx, new_data_node) return new_data_node