| 1750 | return n |
| 1751 | |
| 1752 | def getElementById(self, id): |
| 1753 | if id in self._id_cache: |
| 1754 | return self._id_cache[id] |
| 1755 | if not (self._elem_info or self._magic_id_count): |
| 1756 | return None |
| 1757 | |
| 1758 | stack = self._id_search_stack |
| 1759 | if stack is None: |
| 1760 | # we never searched before, or the cache has been cleared |
| 1761 | stack = [self.documentElement] |
| 1762 | self._id_search_stack = stack |
| 1763 | elif not stack: |
| 1764 | # Previous search was completed and cache is still valid; |
| 1765 | # no matching node. |
| 1766 | return None |
| 1767 | |
| 1768 | result = None |
| 1769 | while stack: |
| 1770 | node = stack.pop() |
| 1771 | # add child elements to stack for continued searching |
| 1772 | stack.extend([child for child in node.childNodes |
| 1773 | if child.nodeType in _nodeTypes_with_children]) |
| 1774 | # check this node |
| 1775 | info = self._get_elem_info(node) |
| 1776 | if info: |
| 1777 | # We have to process all ID attributes before |
| 1778 | # returning in order to get all the attributes set to |
| 1779 | # be IDs using Element.setIdAttribute*(). |
| 1780 | for attr in node.attributes.values(): |
| 1781 | if attr.namespaceURI: |
| 1782 | if info.isIdNS(attr.namespaceURI, attr.localName): |
| 1783 | self._id_cache[attr.value] = node |
| 1784 | if attr.value == id: |
| 1785 | result = node |
| 1786 | elif not node._magic_id_nodes: |
| 1787 | break |
| 1788 | elif info.isId(attr.name): |
| 1789 | self._id_cache[attr.value] = node |
| 1790 | if attr.value == id: |
| 1791 | result = node |
| 1792 | elif not node._magic_id_nodes: |
| 1793 | break |
| 1794 | elif attr._is_id: |
| 1795 | self._id_cache[attr.value] = node |
| 1796 | if attr.value == id: |
| 1797 | result = node |
| 1798 | elif node._magic_id_nodes == 1: |
| 1799 | break |
| 1800 | elif node._magic_id_nodes: |
| 1801 | for attr in node.attributes.values(): |
| 1802 | if attr._is_id: |
| 1803 | self._id_cache[attr.value] = node |
| 1804 | if attr.value == id: |
| 1805 | result = node |
| 1806 | if result is not None: |
| 1807 | break |
| 1808 | return result |
| 1809 | |