diff --git a/sat/tools/xml_tools.py b/sat/tools/xml_tools.py index e578868b..caafbdc8 100644 --- a/sat/tools/xml_tools.py +++ b/sat/tools/xml_tools.py @@ -20,7 +20,7 @@ from collections import OrderedDict import html.entities import re -from typing import Dict, Optional, Tuple, Union, Literal, overload +from typing import Dict, Optional, Tuple, Union, Literal, overload, Iterable from xml.dom import NotFoundErr, minidom import xml.etree.ElementTree as ET from lxml import etree @@ -1926,15 +1926,32 @@ def findAll(elt, namespaces=None, names=None): yield found -def findAncestor(elt, name: str, namespace: Optional[str] = None) -> domish.Element: - """Retrieve ancestor of an element""" +def findAncestor( + elt, + name: str, + namespace: Optional[Union[str, Iterable[str]]] = None + ) -> domish.Element: + """Retrieve ancestor of an element + + @param elt: starting element, its parent will be checked recursively until the + required one if found + @param name: name of the element to find + @param namespace: namespace of the element to find + - None to find any element with that name + - a simple string to find the namespace + - several namespaces can be specified in an iterable, if an element with any of + this namespace and given name is found, it will match + + """ + if isinstance(namespace, str): + namespace = [namespace] current = elt.parent while True: if current is None: raise exceptions.NotFound( f"Can't find any ancestor {name!r} (xmlns: {namespace!r})" ) - if current.name == name and (namespace is None or current.uri == namespace): + if current.name == name and (namespace is None or current.uri in namespace): return current current = current.parent