Esempio n. 1
0
def _create_xml_node(xast, node, context, insert_index=None):
    if isinstance(xast, ast.Step):
        if isinstance(xast.node_test, ast.NameTest):
            # check the predicates (if any) to verify they're constructable
            for pred in xast.predicates:
                if not _predicate_is_constructible(pred):
                    msg = (
                        "Missing element for '%s', and node creation is "
                        + "supported only for simple child and attribute "
                        + "nodes with simple predicates."
                    ) % (serialize(xast),)
                    raise Exception(msg)

            # create the node itself
            if xast.axis in (None, "child"):
                new_node = _create_child_node(node, context, xast, insert_index)
            elif xast.axis in ("@", "attribute"):
                new_node = _create_attribute_node(node, context, xast)

            # and create any nodes necessary for the predicates
            for pred in xast.predicates:
                _construct_predicate(pred, new_node, context)

            return new_node

        # if this is a text() node, we don't need to create anything further
        # return the node that will be parent to text()
        elif _is_text_nodetest(xast):
            return node

    elif isinstance(xast, ast.BinaryExpression):
        if xast.op == "/":
            left_xpath = serialize(xast.left)
            left_node = _find_xml_node(left_xpath, node, context)
            if left_node is None:
                left_node = _create_xml_node(xast.left, node, context)
            return _create_xml_node(xast.right, left_node, context)

    # anything else, throw an exception:
    msg = (
        "Missing element for '%s', and node creation is supported " + "only for simple child and attribute nodes."
    ) % (serialize(xast),)
    raise Exception(msg)
Esempio n. 2
0
    def set(self, xpath, xast, node, context, mapper, value):
        xvalue = mapper.to_xml(value)
        match = _find_xml_node(xpath, node, context)

        if xvalue is None:
            # match must be None. if it exists, delete it.
            if match is not None:
                removed = _remove_xml(xast, node, context)
                # if a node can't be removed, warn since it could have unexpected results
                if not removed:
                    logger.warn("""Could not remove xml for '%s' from %r""" % (serialize(xast), node))
        else:
            if match is None:
                match = _create_xml_node(xast, node, context)
            # terminal (rightmost) step informs how we update the xml
            step = _find_terminal_step(xast)
            _set_in_xml(match, xvalue, context, step)
Esempio n. 3
0
def _remove_xml(xast, node, context):
    "Remove a node or attribute; returns True when something is deleted"
    if isinstance(xast, ast.Step):
        if isinstance(xast.node_test, ast.NameTest):
            if xast.axis in (None, "child"):
                return _remove_child_node(node, context, xast)
            elif xast.axis in ("@", "attribute"):
                return _remove_attribute_node(node, context, xast)
        # special case for text()
        # since it can't be removed, at least clear out any value in the text node
        elif _is_text_nodetest(xast):
            node.text = ""
            return True
    elif isinstance(xast, ast.BinaryExpression):
        if xast.op == "/":
            left_xpath = serialize(xast.left)
            left_node = _find_xml_node(left_xpath, node, context)
            if left_node is not None:
                return _remove_xml(xast.right, left_node, context)
    return False
 def round_trip(self, xpath_str):
     xp = xpath.parse(xpath_str)
     self.assertEqual(xpath_str, serialize(xp))
Esempio n. 5
0
def _remove_child_node(node, context, xast):
    xpath = serialize(xast)
    child = _find_xml_node(xpath, node, context)
    if child is not None:
        node.remove(child)
        return True