comparison sat/tools/xml_tools.py @ 4010:818db4ca3717

tools (xml_tools): accept several namespaces in `findAncestor`
author Goffi <goffi@goffi.org>
date Thu, 16 Mar 2023 16:43:08 +0100
parents f461f11ea176
children bb211f80c3e6
comparison
equal deleted inserted replaced
4009:48e8b3dba793 4010:818db4ca3717
18 18
19 19
20 from collections import OrderedDict 20 from collections import OrderedDict
21 import html.entities 21 import html.entities
22 import re 22 import re
23 from typing import Dict, Optional, Tuple, Union, Literal, overload 23 from typing import Dict, Optional, Tuple, Union, Literal, overload, Iterable
24 from xml.dom import NotFoundErr, minidom 24 from xml.dom import NotFoundErr, minidom
25 import xml.etree.ElementTree as ET 25 import xml.etree.ElementTree as ET
26 from lxml import etree 26 from lxml import etree
27 27
28 from twisted.internet import defer 28 from twisted.internet import defer
1924 yield child 1924 yield child
1925 for found in findAll(child, namespaces, names): 1925 for found in findAll(child, namespaces, names):
1926 yield found 1926 yield found
1927 1927
1928 1928
1929 def findAncestor(elt, name: str, namespace: Optional[str] = None) -> domish.Element: 1929 def findAncestor(
1930 """Retrieve ancestor of an element""" 1930 elt,
1931 name: str,
1932 namespace: Optional[Union[str, Iterable[str]]] = None
1933 ) -> domish.Element:
1934 """Retrieve ancestor of an element
1935
1936 @param elt: starting element, its parent will be checked recursively until the
1937 required one if found
1938 @param name: name of the element to find
1939 @param namespace: namespace of the element to find
1940 - None to find any element with that name
1941 - a simple string to find the namespace
1942 - several namespaces can be specified in an iterable, if an element with any of
1943 this namespace and given name is found, it will match
1944
1945 """
1946 if isinstance(namespace, str):
1947 namespace = [namespace]
1931 current = elt.parent 1948 current = elt.parent
1932 while True: 1949 while True:
1933 if current is None: 1950 if current is None:
1934 raise exceptions.NotFound( 1951 raise exceptions.NotFound(
1935 f"Can't find any ancestor {name!r} (xmlns: {namespace!r})" 1952 f"Can't find any ancestor {name!r} (xmlns: {namespace!r})"
1936 ) 1953 )
1937 if current.name == name and (namespace is None or current.uri == namespace): 1954 if current.name == name and (namespace is None or current.uri in namespace):
1938 return current 1955 return current
1939 current = current.parent 1956 current = current.parent
1940 1957
1941 1958
1942 def pFmtElt(elt, indent=0, defaultUri=""): 1959 def pFmtElt(elt, indent=0, defaultUri=""):