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 _select(self, x12path): """ Get the child node at the path @param x12path: x12 map path @type x12path: L{path<path.X12Path>} """ if len(x12path.loop_list) == 0: # Only segment left cur_node_id = x12path.seg_id qual = x12path.id_val for child in [x for x in self.children if x.type is not None]: if child.type == 'seg': if child.x12_map_node.is_match_qual( child.seg_data, cur_node_id, qual): yield child else: if child.id == cur_node_id: yield child else: cur_node_id = x12path.loop_list[0] cur_loop_list = x12path.loop_list[1:] for child in [x for x in self.children if x.type is not None]: if child.id == cur_node_id: if len(cur_loop_list) == 0 and x12path.seg_id is None: yield child else: child_path = path.X12Path(x12path.format()) child_path.loop_list = cur_loop_list for n in child._select(child_path): yield n
def exists(self, x12_path_str): """ Does at least one child at the x12 path exist? @param x12_path_str: Relative X12 path - 2400/2430 @type x12_path_str: string @return: True if found @rtype: boolean """ (curr, new_path) = self._get_start_node(x12_path_str) xpath = path.X12Path(new_path) for n in curr._select(xpath): return True return False
def count(self, x12_path_str): """ Get a count of sub-nodes at the relative X12 path. @param x12_path_str: Relative X12 path - 2400/2430 @type x12_path_str: string @return: Count of matching sub-nodes @rtype: int """ ct = 0 (curr, new_path) = self._get_start_node(x12_path_str) xpath = path.X12Path(new_path) for n in curr._select(xpath): ct += 1 return ct
def delete_node(self, x12_path_str): """ Delete the first node at the given relative path. If the path is not a valid relative path, return False If multiple values exist, this function deletes the first. @return: True if found and deleted, else False @rtype: Boolean @raise X12PathError: On blank or invalid path @todo: Check counts? """ (curr, new_path) = self._get_start_node(x12_path_str) xpath = path.X12Path(new_path) for n in curr._select(xpath): n.delete() return True return False
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 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 select(self, x12_path_str): """ Get a slice of sub-nodes at the relative X12 path. @note: All interaction/modification with a X12DataNode tree (having a loop root) is done in place. @param x12_path_str: Relative X12 path - 2400/2430 @type x12_path_str: string @return: Iterator on the matching sub-nodes, relative to the instance. @rtype: L{node<x12context.X12DataNode>} """ (curr, new_path) = self._get_start_node(x12_path_str) xpath = path.X12Path(new_path) for n in curr._select(xpath): if xpath.seg_id is not None: assert n.id == xpath.seg_id else: assert len(xpath.loop_list) > 0 assert n.id == xpath.loop_list[-1] assert n.parent is not None, 'Node "%s" has no parent' % (n.id) yield n
def get_value(self, x12_path_str): """ Returns the element value 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. If multiple values exist, this function returns the first. @param x12_path_str: Relative X12 Path @type x12_path_str: string @return: the element value at the relative X12 path @rtype: string @raise X12PathError: On blank or invalid path """ (curr, new_path) = self._get_start_node(x12_path_str) seg_data = curr.get_first_matching_segment(new_path) if seg_data is None: return None xpath = path.X12Path(new_path) xpath.loop_list = [] xpath.id_val = None seg_part = xpath.format() return seg_data.get_value(seg_part)