def removeChild(self, child, end_tag_too=True): """ Remove subelement (`child`) specified by reference. Note: This can't be used for removing subelements by value! If you want to do such thing, try:: for e in dom.find("value"): dom.removeChild(e) Args: child (obj): :class:`HTMLElement` instance which will be removed from this element. end_tag_too (bool, default True): Remove also `child` endtag. """ # if there are multiple childs, remove them if _is_iterable(child): map(lambda x: self.removeChild(x, end_tag_too), child) return if not self.childs: return end_tag = None if end_tag_too: end_tag = child.endtag for e in self.childs: if e != child: e.removeChild(child, end_tag_too) continue if end_tag_too and end_tag in self.childs: self.childs.remove(end_tag) self.childs.remove(e)
def match(self, *args, **kwargs): """ :meth:`wfind` is nice function, but still kinda long to use, because you have to manually chain all calls together and in the end, you get :class:`HTMLElement` instance container. This function recursively calls :meth:`wfind` for you and in the end, you get list of matching elements:: xe = dom.match("root", "some", "something", "xe") is alternative to:: xe = dom.wfind("root").wfind("some").wfind("something").wfind("xe") You can use all arguments used in :meth:`wfind`:: dom = dhtmlparser.parseString(''' <root> <div id="1"> <div id="5"> <xe id="wanted xe" /> </div> <div id="10"> <xe id="another wanted xe" /> </div> <xe id="another xe" /> </div> <div id="2"> <div id="20"> <xe id="last wanted xe" /> </div> </div> </root> ''') xe = dom.match( "root", {"tag_name": "div", "params": {"id": "1"}}, ["div", {"id": "5"}], "xe" ) assert len(xe) == 1 assert xe[0].params["id"] == "wanted xe" Args: *args: List of :meth:`wfind` parameters. absolute (bool, default None): If true, first element will be searched from the root of the DOM. If None, :attr:`_container` attribute will be used to decide value of this argument. If False, :meth:`find` call will be run first to find first element, then :meth:`wfind` will be used to progress to next arguments. Returns: list: List of matching elements (empty list if no matching element\ is found). """ if not args: return self.childs # pop one argument from argument stack (tuples, so .pop() won't work) act = args[0] args = args[1:] # this is used to define relative/absolute root of the first element def wrap_find(*args, **kwargs): """ Find wrapper, to allow .wfind() to be substituted witřh .find() call, which normally returns blank array instead of blank `container` element. """ el = self.__class__() # HTMLElement() el.childs = self.find(*args, **kwargs) return el # if absolute is not specified (ie - next recursive call), use # self._container, which is set to True by .wfind(), so next search # will be absolute from the given element absolute = kwargs.get("absolute", None) if absolute is None: absolute = self._container find_func = self.wfind if absolute else wrap_find result = None if _is_iterable(act): result = find_func(*act) elif _is_dict(act): result = find_func(**act) elif _is_str(act): result = find_func(act) else: raise KeyError( "Unknown parameter type '%s': %s" % (type(act), act) ) if not result.childs: return [] match = result.match(*args) # just to be sure return always blank array, when the match is # False/None and so on (it shouldn't be, but ..) return match if match else []