Skip to content

deletion

deletion

Shared bookkeeping for removing content from a document.

Removing an element is one line of lxml. Removing it safely is not: the content may have carried the only reference to a hyperlink relationship, or one half of a comment range or bookmark, and dropping it without tidying those leaves a document Word either repairs on open or refuses outright.

delete_element

delete_element(
    element: BaseOxmlElement, part: Part | None
) -> None

Remove element from its tree, tidying what it referred to.

Any relationship referenced only from inside element is dropped, and the surviving half of any range marker whose partner is inside element is removed too, so no dangling w:bookmarkStart or w:commentRangeStart is left behind.

part may be None for an element not attached to a package, in which case the relationship cleanup is skipped.

Source code in src/docx/oxml/deletion.py
def delete_element(element: BaseOxmlElement, part: Part | None) -> None:
    """Remove `element` from its tree, tidying what it referred to.

    Any relationship referenced only from inside `element` is dropped, and the surviving
    half of any range marker whose partner is inside `element` is removed too, so no
    dangling `w:bookmarkStart` or `w:commentRangeStart` is left behind.

    `part` may be |None| for an element not attached to a package, in which case the
    relationship cleanup is skipped.
    """
    _remove_orphaned_range_markers(element)
    rIds = _rIds_within(element) if part is not None else []

    parent = element.getparent()
    if parent is not None:
        parent.remove(element)

    if part is not None:
        for rId in rIds:
            # -- the element is gone, so a remaining reference is a real one. Note this
            # -- is not `Part.drop_rel()`, whose threshold assumes the caller's own
            # -- reference is still in the XML. --
            if rId in part.rels and _rel_ref_count(part, rId) == 0:
                del part.rels[rId]