docs: def _remove_xml(xast, node, context, if_empty=False):
      '''Remove a node or attribute.  For multipart XPaths that are
      constructible by :mod:`eulxml.xmlmap`, the corresponding nodes
      will be removed if they are empty (other than predicates specified
      in the XPath).
  
      :param xast: parsed xpath (xpath abstract syntax tree) from
  	:mod:`eulxml.xpath`
      :param node: lxml node relative to which xast should be removed
      :param context: any context required for the xpath (e.g.,
      	namespace definitions)
      :param if_empty: optional boolean; only remove a node if it is
  	empty (no attributes and no child nodes); defaults to False
  
      :returns: True if something was 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, if_empty=if_empty)
              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
  
      # If the xpath is a multi-step path (e.g., foo[@id="a"]/bar[@id="b"]/baz),
      # remove the leaf node.  If the remaining portions of that path
      # could have been constructed when setting the node and are empty
      # (other than any predicates defined in the xpath), remove them as well.
      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:
                  # remove the last element in the xpath
                  removed = _remove_xml(xast.right, left_node, context,
                                        if_empty=if_empty) # honor current if_empty flag
  
                  # If the left portion of the xpath is something we
                  # could have constructed, remove it if it is empty.
                  if removed and _predicate_is_constructible(left_xpath):
                      _remove_xml(xast.left, node, context, if_empty=True)
  
                  # report on whether the leaf node was removed or not,
                  # regardless of what was done with left portion of the path
                  return removed
  
      return False