@@ -1277,52 +1277,61 @@ cdef public class _Element [ type LxmlElementType, object LxmlElement ]:
12771277 return None
12781278 return _elementFactory(self ._doc, c_node)
12791279
1280- def itersiblings (self , tag = None , *, preceding = False ):
1281- u """ itersiblings(self, tag=None, preceding=False)
1280+ def itersiblings (self , tag = None , *tags , preceding = False ):
1281+ u """ itersiblings(self, tag=None, *tags, preceding=False)
12821282
12831283 Iterate over the following or preceding siblings of this element.
12841284
12851285 The direction is determined by the 'preceding' keyword which
12861286 defaults to False, i.e. forward iteration over the following
12871287 siblings. When True, the iterator yields the preceding
12881288 siblings in reverse document order, i.e. starting right before
1289- the current element and going left. The generated elements
1290- can be restricted to a specific tag name with the 'tag'
1291- keyword.
1289+ the current element and going backwards.
1290+
1291+ The returned elements can be restricted to a specific tag name by
1292+ passing a tag or a series of tag names.
12921293 """
1293- return SiblingsIterator(self , tag, preceding = preceding)
1294+ if tag is not None :
1295+ tags += (tag,)
1296+ return SiblingsIterator(self , tags, preceding = preceding)
12941297
1295- def iterancestors (self , tag = None ):
1296- u """ iterancestors(self, tag=None)
1298+ def iterancestors (self , tag = None , * tags ):
1299+ u """ iterancestors(self, tag=None, *tags )
12971300
12981301 Iterate over the ancestors of this element (from parent to parent).
12991302
1300- The generated elements can be restricted to a specific tag name with
1301- the ' tag' keyword .
1303+ The returned elements can be restricted to a specific tag name by
1304+ passing a tag or a series of tag names .
13021305 """
1303- return AncestorsIterator(self , tag)
1306+ if tag is not None :
1307+ tags += (tag,)
1308+ return AncestorsIterator(self , tags)
13041309
1305- def iterdescendants (self , tag = None ):
1306- u """ iterdescendants(self, tag=None)
1310+ def iterdescendants (self , tag = None , * tags ):
1311+ u """ iterdescendants(self, tag=None, *tags )
13071312
13081313 Iterate over the descendants of this element in document order.
13091314
13101315 As opposed to ``el.iter()``, this iterator does not yield the element
1311- itself. The generated elements can be restricted to a specific tag
1312- name with the ' tag' keyword .
1316+ itself. The returned elements can be restricted to a specific tag
1317+ name by passing a tag or a series of tag names .
13131318 """
1314- return ElementDepthFirstIterator(self , tag, inclusive = False )
1319+ if tag is not None :
1320+ tags += (tag,)
1321+ return ElementDepthFirstIterator(self , tags, inclusive = False )
13151322
1316- def iterchildren (self , tag = None , *, reversed = False ):
1317- u """ iterchildren(self, tag=None, reversed=False)
1323+ def iterchildren (self , tag = None , *tags , reversed = False ):
1324+ u """ iterchildren(self, tag=None, *tags, reversed=False)
13181325
13191326 Iterate over the children of this element.
13201327
1321- As opposed to using normal iteration on this element, the generated
1322- elements can be restricted to a specific tag name with the ' tag'
1323- keyword and reversed with the 'reversed' keyword.
1328+ As opposed to using normal iteration on this element, the returned
1329+ elements can be restricted to a specific tag name by passing a tag
1330+ or a series of tag names, and reversed with the 'reversed' keyword.
13241331 """
1325- return ElementChildIterator(self , tag, reversed = reversed )
1332+ if tag is not None :
1333+ tags += (tag,)
1334+ return ElementChildIterator(self , tags, reversed = reversed )
13261335
13271336 def getroottree (self ):
13281337 u """ getroottree(self)
@@ -1336,15 +1345,17 @@ cdef public class _Element [ type LxmlElementType, object LxmlElement ]:
13361345 _assertValidDoc(self ._doc)
13371346 return _elementTreeFactory(self ._doc, None )
13381347
1339- def getiterator (self , tag = None ):
1340- u """ getiterator(self, tag=None)
1348+ def getiterator (self , tag = None , * tags ):
1349+ u """ getiterator(self, tag=None, *tags )
13411350
13421351 Returns a sequence or iterator of all elements in the subtree in
13431352 document order (depth first pre-order), starting with this
13441353 element.
13451354
13461355 Can be restricted to find only elements with a specific tag
1347- (pass ``tag="xyz"``) or from a namespace (pass ``tag="{ns}*"``).
1356+ (pass ``"xyz"`` as tag) or from a namespace (pass ``"{ns}*"`` as tag).
1357+ Passing a sequence of tags will let the iterator return all
1358+ elements matching any of these tags, in document order.
13481359
13491360 You can also pass the Element, Comment, ProcessingInstruction and
13501361 Entity factory functions to look only for the specific element type.
@@ -1357,34 +1368,43 @@ cdef public class _Element [ type LxmlElementType, object LxmlElement ]:
13571368 method in new code if you require backwards compatibility
13581369 with older versions of lxml or ElementTree.
13591370 """
1360- return ElementDepthFirstIterator(self , tag)
1371+ if tag is not None :
1372+ tags += (tag,)
1373+ return ElementDepthFirstIterator(self , tags)
13611374
1362- def iter (self , tag = None ):
1363- u """ iter(self, tag=None)
1375+ def iter (self , tag = None , * tags ):
1376+ u """ iter(self, tag=None, *tags )
13641377
13651378 Iterate over all elements in the subtree in document order (depth
13661379 first pre-order), starting with this element.
13671380
13681381 Can be restricted to find only elements with a specific tag
1369- (pass ``tag="xyz"``) or from a namespace (pass ``tag="{ns}*"``).
1382+ (pass ``"xyz"`` as tag) or from a namespace (pass ``"{ns}*"`` as tag).
1383+ Passing a sequence of tags will let the iterator return all
1384+ elements matching any of these tags, in document order.
13701385
13711386 You can also pass the Element, Comment, ProcessingInstruction and
13721387 Entity factory functions to look only for the specific element type.
13731388 """
1374- return ElementDepthFirstIterator(self , tag)
1389+ if tag is not None :
1390+ tags += (tag,)
1391+ return ElementDepthFirstIterator(self , tags)
13751392
1376- def itertext (self , tag = None , *, with_tail = True ):
1377- u """ itertext(self, tag=None, with_tail=True)
1393+ def itertext (self , tag = None , *tags , with_tail = True ):
1394+ u """ itertext(self, tag=None, *tags, with_tail=True)
13781395
13791396 Iterates over the text content of a subtree.
13801397
1381- You can pass the ``tag`` keyword argument to restrict text content to
1382- a specific tag name.
1398+ You can pass a tag name to restrict text content to a specific tag
1399+ name. Passing a sequence of tags will let the iterator consider
1400+ all elements matching any of these tags.
13831401
13841402 You can set the ``with_tail`` keyword argument to ``False`` to skip
13851403 over tail text.
13861404 """
1387- return ElementTextIterator(self , tag, with_tail = with_tail)
1405+ if tag is not None :
1406+ tags += (tag,)
1407+ return ElementTextIterator(self , tags, with_tail = with_tail)
13881408
13891409 def makeelement (self , _tag , attrib = None , nsmap = None , **_extra ):
13901410 u """ makeelement(self, _tag, attrib=None, nsmap=None, **_extra)
@@ -1915,15 +1935,16 @@ cdef public class _ElementTree [ type LxmlElementTreeType,
19151935 tree.xmlFree(c_path)
19161936 return path
19171937
1918- def getiterator (self , tag = None ):
1919- u """ getiterator(self, tag=None)
1938+ def getiterator (self , tag = None , * tags ):
1939+ u """ getiterator(self, *tags, tag=None)
19201940
19211941 Returns a sequence or iterator of all elements in document order
19221942 (depth first pre-order), starting with the root element.
19231943
19241944 Can be restricted to find only elements with a specific tag
1925- (pass ``tag="xyz"`` or ``tag="{ns}xyz"``) or from a namespace
1926- (pass ``tag="{ns}*"``).
1945+ (pass ``"xyz"`` as tag) or from a namespace (pass ``"{ns}*"`` as tag).
1946+ Passing a sequence of tags will let the iterator return all
1947+ elements matching any of these tags, in document order.
19271948
19281949 You can also pass the Element, Comment, ProcessingInstruction and
19291950 Entity factory functions to look only for the specific element type.
@@ -1939,18 +1960,22 @@ cdef public class _ElementTree [ type LxmlElementTreeType,
19391960 root = self .getroot()
19401961 if root is None :
19411962 return ()
1942- return root.getiterator(tag)
1963+ if tag is not None :
1964+ tags += (tag,)
1965+ return root.getiterator(* tags)
19431966
1944- def iter (self , tag = None ):
1945- u """ iter(self, tag=None)
1967+ def iter (self , tag = None , * tags ):
1968+ u """ iter(self, tag=None, *tags )
19461969
19471970 Creates an iterator for the root element. The iterator loops over
19481971 all elements in this tree, in document order.
19491972 """
19501973 root = self .getroot()
19511974 if root is None :
19521975 return ()
1953- return root.iter(tag)
1976+ if tag is not None :
1977+ tags += (tag,)
1978+ return root.iter(* tags)
19541979
19551980 def find (self , path , namespaces = None ):
19561981 u """ find(self, path, namespaces=None)
@@ -2424,24 +2449,24 @@ cdef class _MultiTagMatcher:
24242449 self ._tag_count = 0
24252450 if self ._cached_tags:
24262451 for i in xrange (count):
2427- python .Py_XDECREF(self ._cached_tags[i].href)
2452+ cpython.ref .Py_XDECREF(self ._cached_tags[i].href)
24282453 cpython.mem.PyMem_Free(self ._cached_tags)
24292454 self ._cached_tags = NULL
24302455
24312456 cdef initTagMatch(self , tags):
24322457 self ._cached_doc = None
24332458 del self ._py_tags[:]
24342459 self ._clear()
2435- if tags is None :
2436- # match anything
2460+ if tags is None or tags == () :
2461+ # no selection in tags argument => match anything
24372462 self ._node_types = (
24382463 1 << tree.XML_COMMENT_NODE |
24392464 1 << tree.XML_PI_NODE |
24402465 1 << tree.XML_ENTITY_REF_NODE |
24412466 1 << tree.XML_ELEMENT_NODE)
2442- return
2443- self ._node_types = 0
2444- self ._storeTags(tags, set ())
2467+ else :
2468+ self ._node_types = 0
2469+ self ._storeTags(tags, set ())
24452470
24462471 cdef _storeTags(self , tag, set seen):
24472472 if tag is Comment:
@@ -2456,10 +2481,13 @@ cdef class _MultiTagMatcher:
24562481 if tag in seen:
24572482 return
24582483 seen.add(tag)
2459- href, name = _getNsTag(tag)
2460- if name == b' *' :
2461- name = None
2462- self ._py_tags.append((href, name))
2484+ if tag in (' *' , ' {*}*' ):
2485+ self ._node_types |= 1 << tree.XML_ELEMENT_NODE
2486+ else :
2487+ href, name = _getNsTag(tag)
2488+ if name == b' *' :
2489+ name = None
2490+ self ._py_tags.append((href, name))
24632491 else :
24642492 # support a sequence of tags
24652493 for item in tag:
@@ -2476,6 +2504,7 @@ cdef class _MultiTagMatcher:
24762504 self ._tag_count = 0
24772505 if not self ._py_tags:
24782506 self ._cached_doc = doc
2507+ self ._cached_size = dict_size
24792508 return 0
24802509 if not self ._cached_tags:
24812510 self ._cached_tags = < qname* > cpython.mem.PyMem_Malloc(len (self ._py_tags) * sizeof(qname))
@@ -2599,7 +2628,7 @@ cdef class ElementDepthFirstIterator:
25992628 instructions. To filter them out, check if the ``tag`` property
26002629 of the returned element is a string (i.e. not None and not a
26012630 factory function), or pass the ``Element`` factory for the ``tag``
2602- keyword .
2631+ argument to receive only Elements .
26032632
26042633 If the optional ``tag`` argument is not None, the iterator returns only
26052634 the elements that match the respective name and namespace.
0 commit comments