Previously, you could use the .elements() method to find matching elements nested within an HTML helper object (such as a form), and you could mutuate the matched elements (e.g., add attributes and insert components), but you could not completely replace or remove the matched elements. The only way to replace or remove elements was to use list indexing (e.g., form[0][0][1], etc.), but that requires you to know the exact index values ahead of time. Now (in trunk) you can use the .elements() method to replace or remove nested elements or text using the new "replace" and "find_text" arguments. Below is the updated docstring, including some examples (will be added to the book as well). Please test and report any problems (particularly if any of the old .elements() functionality has broken).
Anthony Docstring: Elements that are matched can also be replaced or removed by specifying a "replace" argument (note, a list of the original matching elements is still returned as usual). >>> a = DIV(DIV(SPAN('x', _class='abc'), DIV(SPAN('y', _class='abc'), SPAN('z', _class='abc')))) >>> b = a.elements('span.abc', replace=P('x', _class='xyz')) >>> print a <div><div><p class="xyz">x</p><div><p class="xyz">x</p><p class="xyz">x</p></div></div></div> "replace" can be a callable, which will be passed the original element and should return a new element to replace it. >>> a = DIV(DIV(SPAN('x', _class='abc'), DIV(SPAN('y', _class='abc'), SPAN('z', _class='abc')))) >>> b = a.elements('span.abc', replace=lambda el: P(el[0], _class='xyz')) >>> print a <div><div><p class="xyz">x</p><div><p class="xyz">y</p><p class="xyz">z</p></div></div></div> If replace=None, matching elements will be removed completely. >>> a = DIV(DIV(SPAN('x', _class='abc'), DIV(SPAN('y', _class='abc'), SPAN('z', _class='abc')))) >>> b = a.elements('span', find='y', replace=None) >>> print a <div><div><span class="abc">x</span><div><span class="abc">z</span></div></div></div> If a "find_text" argument is specified, elements will be searched for text components that match find_text, and any matching text components will be replaced (find_text is ignored if "replace" is not also specified). Like the "find" argument, "find_text" can be a string or a compiled regex. >>> a = DIV(DIV(SPAN('x', _class='abc'), DIV(SPAN('y', _class='abc'), SPAN('z', _class='abc')))) >>> b = a.elements(find_text=re.compile('x|y|z'), replace='hello') >>> print a <div><div><span class="abc">hello</span><div><span class="abc">hello</span><span class="abc">hello</span></div></div></div> If other attributes are specified along with find_text, then only components that match the specified attributes will be searched for find_text. >>> a = DIV(DIV(SPAN('x', _class='abc'), DIV(SPAN('y', _class='efg'), SPAN('z', _class='abc')))) >>> b = a.elements('span.efg', find_text=re.compile('x|y|z'), replace='hello') >>> print a <div><div><span class="abc">x</span><div><span class="efg">hello</span><span class="abc">z</span></div></div></div> --