Example #1
0
 def _before_delete_node(self, node):
     """ check if a text node will be inserted with a sibbling text node to
     avoid coalescing two text nodes
     """
     k = get_pos(node)
     parent = node[N_PARENT]
     if k >= 1 and k+1 < len(parent[N_CHILDS]):
         if parent[N_CHILDS][k-1][N_TYPE] == NT_TEXT and \
            parent[N_CHILDS][k+1][N_TYPE] == NT_TEXT:
             tag = self.FAKE_TAG[:]
             self.add_action(['insert-after', f_xpath(parent[N_CHILDS][k-1]), tag])
             insert_node(parent, tag, k)
             return parent, k
     return None
Example #2
0
 def _before_insert_text(self, parent, new_text, k):
     """ check if a text node that will be remove has two sibbling text nodes
     to avoid coalescing two text nodes
     """
     if k > 1:
         if parent[N_CHILDS][k-1][N_TYPE] == NT_TEXT:
             tag = self.FAKE_TAG[:]
             self.add_action(['insert-after', f_xpath(parent[N_CHILDS][k-1]), tag])
             insert_node(parent, tag, k)
             return k+1
     if k < len(parent[N_CHILDS]):
         if parent[N_CHILDS][k][N_TYPE] == NT_TEXT:
             tag = self.FAKE_TAG[:]
             if k <= nb_attrs(parent):
                 self.add_action(['append_first', f_xpath(parent), tag])
             else:
                 self.add_action(['insert-after', f_xpath(parent[N_CHILDS][k]), tag])
             insert_node(parent, tag, k)                
     return k
Example #3
0
    def _make_move(self, n1, n2, k):
        # avoid coalescing two text nodes
        act_node = self._before_delete_node(n1)
        if act_node is not None and act_node[0] is n2 and act_node[1] < k:
            k += 1
        if n1[N_TYPE] == NT_TEXT:
            k = self._before_insert_text(n2, n1, k)
        # avoid moving an attribute node on 
        elif n1[N_TYPE] == NT_ATTN: 
##             n2[N_NAME] = 'A@LogilabXmldiffTmpAttr:%s'%n2[N_NAME][2:]
##             n2[N_NAME] = '@LogilabXmldiffTmpAttr_%s'%n2[N_NAME]
##             n2[N_VALUE] = 'LogilabXmldiffTmpAttr_%s'%n2[N_VALUE]
##             self.add_action(['move-and-rename_node', n1, n2])
##             self.add_action(['rename_node', f_xpath(n2), n2[N_NAME][23:]])
            # avoid moving attribute node from a place to another on the same node
            if not n1[N_PARENT] is n2:
                self.add_action(['move', n1, n2])
        elif k <= nb_attrs(n2):
            self.add_action(['move-first', n1, n2])
        else:
            self.add_action(['move-after', n1, n2[N_CHILDS][k-1]])
        # real move
        delete_node(n1)
        insert_node(n2, n1, k)
Example #4
0
 def _fmes_step1(self, tree2, tree1):
     """ first step of the edit script algorithm
     combines the update, insert, align and move phases
     """
     mapping = self._mapping
     fp = self._find_pos
     al = self._align_children
     _partner = partner
     # x the current node in the breadth-first order traversal
     for x in make_bfo_list(tree2):
         y = x[N_PARENT]
         z = _partner(1, y)
         w = _partner(1, x)
         # insert
         if not w:
             todo = 1
             # avoid to add existing attribute node
             if x[N_TYPE] == NT_ATTN:
                 for n in z[N_CHILDS]:
                     if n[N_TYPE] != NT_ATTN:
                         break
                     elif n[N_VALUE] == x[N_VALUE]:
                         # FIXME: n should yet be mapped
                         todo = None
                         w = n
                         w[N_MAPPED] = TRUE
                         mapping.append((w, x))
                         delete_node(w[N_CHILDS][0])
                         break
             if todo is not None:
                 x[N_INORDER] = TRUE
                 k = fp(x)
                 # w = copy(x)
                 w = x[:]
                 w[N_CHILDS] = []
                 w.append(TRUE) # <-> w[N_MAPPED] = TRUE
                 mapping.append((w, x))
                 # avoid coalescing two text nodes
                 if w[N_TYPE] == NT_TEXT:
                     k = self._before_insert_text(z, w, k)
                 # real insert on tree 1
                 insert_node(z, w, k)
                 # make actions on subtree
                 self._dict[id(w)] = ww = w[:]
                 ww[N_CHILDS] = []
                 # preformat action
                 if not self._dict.has_key(id(z)):
                     if w[N_TYPE] == NT_ATTV:
                         action = ['update', f_xpath(z), w[N_VALUE]]
                     elif w[N_TYPE] == NT_ATTN:
                         action = ['append', f_xpath(z), ww]
                     elif z[N_TYPE] == NT_ROOT:
                         action = ['append-first', '/', ww]
                     else:
                         if ww[N_VALUE] == "spoken-languages":
                             self.test = ww
                         k = get_pos(w)
                         if k <= nb_attrs(z):
                             action = ['append-first', f_xpath(z), ww]
                         else:
                             action = ['insert-after', f_xpath(z[N_CHILDS][k-1]), ww]
                     self.add_action(action)
                 else:
                     insert_node(self._dict[id(z)], ww, k)
         elif x[N_NAME] != '/':
             v = w[N_PARENT]
             # update
             if w[N_VALUE] != x[N_VALUE]:
                 # format action
                 if w[N_TYPE] in (NT_NODE, NT_ATTN):
                     self.add_action(['rename', f_xpath(w), x[N_VALUE]])
                 else:
                     self.add_action(['update', f_xpath(w), x[N_VALUE]])
                 # real update on t1
                 w[N_VALUE] = x[N_VALUE]
                 # this is necessary for xpath
                 rename_node(w, x[N_NAME])
             # move x if parents not mapped together
             if not has_couple(v, y):
                 x[N_INORDER] = TRUE
                 k = fp(x)
                 self._make_move(w, z, k)
         # align children
         al(w, x)