annotate Lib/xml/etree/ElementPath.py @ 79691:05c8928362ee

Merge __next__ method link fixes with 3.3.
author Ezio Melotti <ezio.melotti@gmail.com>
date Fri, 12 Oct 2012 13:46:37 +0300
parents 33a221662f39
children 56a4561600ad
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
1 #
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
2 # ElementTree
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
3 # $Id: ElementPath.py 3375 2008-02-13 08:05:08Z fredrik $
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
4 #
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
5 # limited xpath support for element trees
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
6 #
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
7 # history:
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
8 # 2003-05-23 fl created
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
9 # 2003-05-28 fl added support for // etc
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
10 # 2003-08-27 fl fixed parsing of periods in element names
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
11 # 2007-09-10 fl new selection engine
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
12 # 2007-09-12 fl fixed parent selector
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
13 # 2007-09-13 fl added iterfind; changed findall to return a list
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
14 # 2007-11-30 fl added namespaces support
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
15 # 2009-10-30 fl added child element value filter
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
16 #
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
17 # Copyright (c) 2003-2009 by Fredrik Lundh. All rights reserved.
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
18 #
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
19 # fredrik@pythonware.com
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
20 # http://www.pythonware.com
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
21 #
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
22 # --------------------------------------------------------------------
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
23 # The ElementTree toolkit is
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
24 #
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
25 # Copyright (c) 1999-2009 by Fredrik Lundh
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
26 #
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
27 # By obtaining, using, and/or copying this software and/or its
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
28 # associated documentation, you agree that you have read, understood,
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
29 # and will comply with the following terms and conditions:
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
30 #
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
31 # Permission to use, copy, modify, and distribute this software and
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
32 # its associated documentation for any purpose and without fee is
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
33 # hereby granted, provided that the above copyright notice appears in
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
34 # all copies, and that both that copyright notice and this permission
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
35 # notice appear in supporting documentation, and that the name of
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
36 # Secret Labs AB or the author not be used in advertising or publicity
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
37 # pertaining to distribution of the software without specific, written
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
38 # prior permission.
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
39 #
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
40 # SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
41 # TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
42 # ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
43 # BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
44 # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
45 # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
46 # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
47 # OF THIS SOFTWARE.
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
48 # --------------------------------------------------------------------
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
49
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
50 # Licensed to PSF under a Contributor Agreement.
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
51 # See http://www.python.org/psf/license for licensing details.
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
52
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
53 ##
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
54 # Implementation module for XPath support. There's usually no reason
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
55 # to import this module directly; the <b>ElementTree</b> does this for
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
56 # you, if needed.
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
57 ##
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
58
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
59 import re
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
60
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
61 xpath_tokenizer_re = re.compile(
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
62 "("
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
63 "'[^']*'|\"[^\"]*\"|"
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
64 "::|"
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
65 "//?|"
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
66 "\.\.|"
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
67 "\(\)|"
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
68 "[/.*:\[\]\(\)@=])|"
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
69 "((?:\{[^}]+\})?[^/\[\]\(\)@=\s]+)|"
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
70 "\s+"
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
71 )
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
72
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
73 def xpath_tokenizer(pattern, namespaces=None):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
74 for token in xpath_tokenizer_re.findall(pattern):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
75 tag = token[1]
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
76 if tag and tag[0] != "{" and ":" in tag:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
77 try:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
78 prefix, uri = tag.split(":", 1)
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
79 if not namespaces:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
80 raise KeyError
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
81 yield token[0], "{%s}%s" % (namespaces[prefix], uri)
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
82 except KeyError:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
83 raise SyntaxError("prefix %r not found in prefix map" % prefix)
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
84 else:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
85 yield token
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
86
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
87 def get_parent_map(context):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
88 parent_map = context.parent_map
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
89 if parent_map is None:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
90 context.parent_map = parent_map = {}
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
91 for p in context.root.iter():
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
92 for e in p:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
93 parent_map[e] = p
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
94 return parent_map
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
95
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
96 def prepare_child(next, token):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
97 tag = token[1]
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
98 def select(context, result):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
99 for elem in result:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
100 for e in elem:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
101 if e.tag == tag:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
102 yield e
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
103 return select
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
104
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
105 def prepare_star(next, token):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
106 def select(context, result):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
107 for elem in result:
79389
33a221662f39 more yield from
Philip Jenvey <pjenvey@underboss.org>
parents: 59601
diff changeset
108 yield from elem
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
109 return select
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
110
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
111 def prepare_self(next, token):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
112 def select(context, result):
79389
33a221662f39 more yield from
Philip Jenvey <pjenvey@underboss.org>
parents: 59601
diff changeset
113 yield from result
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
114 return select
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
115
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
116 def prepare_descendant(next, token):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
117 token = next()
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
118 if token[0] == "*":
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
119 tag = "*"
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
120 elif not token[0]:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
121 tag = token[1]
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
122 else:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
123 raise SyntaxError("invalid descendant")
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
124 def select(context, result):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
125 for elem in result:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
126 for e in elem.iter(tag):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
127 if e is not elem:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
128 yield e
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
129 return select
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
130
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
131 def prepare_parent(next, token):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
132 def select(context, result):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
133 # FIXME: raise error if .. is applied at toplevel?
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
134 parent_map = get_parent_map(context)
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
135 result_map = {}
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
136 for elem in result:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
137 if elem in parent_map:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
138 parent = parent_map[elem]
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
139 if parent not in result_map:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
140 result_map[parent] = None
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
141 yield parent
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
142 return select
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
143
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
144 def prepare_predicate(next, token):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
145 # FIXME: replace with real parser!!! refs:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
146 # http://effbot.org/zone/simple-iterator-parser.htm
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
147 # http://javascript.crockford.com/tdop/tdop.html
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
148 signature = []
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
149 predicate = []
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
150 while 1:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
151 token = next()
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
152 if token[0] == "]":
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
153 break
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
154 if token[0] and token[0][:1] in "'\"":
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
155 token = "'", token[0][1:-1]
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
156 signature.append(token[0] or "-")
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
157 predicate.append(token[1])
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
158 signature = "".join(signature)
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
159 # use signature to determine predicate type
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
160 if signature == "@-":
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
161 # [@attribute] predicate
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
162 key = predicate[1]
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
163 def select(context, result):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
164 for elem in result:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
165 if elem.get(key) is not None:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
166 yield elem
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
167 return select
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
168 if signature == "@-='":
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
169 # [@attribute='value']
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
170 key = predicate[1]
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
171 value = predicate[-1]
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
172 def select(context, result):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
173 for elem in result:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
174 if elem.get(key) == value:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
175 yield elem
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
176 return select
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
177 if signature == "-" and not re.match("\d+$", predicate[0]):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
178 # [tag]
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
179 tag = predicate[0]
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
180 def select(context, result):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
181 for elem in result:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
182 if elem.find(tag) is not None:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
183 yield elem
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
184 return select
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
185 if signature == "-='" and not re.match("\d+$", predicate[0]):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
186 # [tag='value']
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
187 tag = predicate[0]
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
188 value = predicate[-1]
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
189 def select(context, result):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
190 for elem in result:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
191 for e in elem.findall(tag):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
192 if "".join(e.itertext()) == value:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
193 yield elem
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
194 break
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
195 return select
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
196 if signature == "-" or signature == "-()" or signature == "-()-":
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
197 # [index] or [last()] or [last()-index]
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
198 if signature == "-":
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
199 index = int(predicate[0]) - 1
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
200 else:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
201 if predicate[0] != "last":
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
202 raise SyntaxError("unsupported function")
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
203 if signature == "-()-":
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
204 try:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
205 index = int(predicate[2]) - 1
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
206 except ValueError:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
207 raise SyntaxError("unsupported expression")
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
208 else:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
209 index = -1
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
210 def select(context, result):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
211 parent_map = get_parent_map(context)
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
212 for elem in result:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
213 try:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
214 parent = parent_map[elem]
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
215 # FIXME: what if the selector is "*" ?
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
216 elems = list(parent.findall(elem.tag))
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
217 if elems[index] is elem:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
218 yield elem
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
219 except (IndexError, KeyError):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
220 pass
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
221 return select
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
222 raise SyntaxError("invalid predicate")
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
223
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
224 ops = {
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
225 "": prepare_child,
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
226 "*": prepare_star,
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
227 ".": prepare_self,
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
228 "..": prepare_parent,
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
229 "//": prepare_descendant,
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
230 "[": prepare_predicate,
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
231 }
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
232
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
233 _cache = {}
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
234
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
235 class _SelectorContext:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
236 parent_map = None
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
237 def __init__(self, root):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
238 self.root = root
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
239
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
240 # --------------------------------------------------------------------
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
241
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
242 ##
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
243 # Generate all matching objects.
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
244
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
245 def iterfind(elem, path, namespaces=None):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
246 # compile selector pattern
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
247 if path[-1:] == "/":
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
248 path = path + "*" # implicit all (FIXME: keep this?)
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
249 try:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
250 selector = _cache[path]
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
251 except KeyError:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
252 if len(_cache) > 100:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
253 _cache.clear()
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
254 if path[:1] == "/":
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
255 raise SyntaxError("cannot use absolute path on element")
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
256 next = iter(xpath_tokenizer(path, namespaces)).__next__
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
257 token = next()
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
258 selector = []
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
259 while 1:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
260 try:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
261 selector.append(ops[token[0]](next, token))
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
262 except StopIteration:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
263 raise SyntaxError("invalid path")
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
264 try:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
265 token = next()
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
266 if token[0] == "/":
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
267 token = next()
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
268 except StopIteration:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
269 break
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
270 _cache[path] = selector
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
271 # execute selector pattern
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
272 result = [elem]
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
273 context = _SelectorContext(elem)
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
274 for select in selector:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
275 result = select(context, result)
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
276 return result
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
277
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
278 ##
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
279 # Find first matching object.
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
280
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
281 def find(elem, path, namespaces=None):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
282 try:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
283 return next(iterfind(elem, path, namespaces))
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
284 except StopIteration:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
285 return None
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
286
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
287 ##
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
288 # Find all matching objects.
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
289
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
290 def findall(elem, path, namespaces=None):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
291 return list(iterfind(elem, path, namespaces))
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
292
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
293 ##
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
294 # Find text for first matching object.
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
diff changeset
295
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
296 def findtext(elem, path, default=None, namespaces=None):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
297 try:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
298 elem = next(iterfind(elem, path, namespaces))
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
299 return elem.text or ""
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
300 except StopIteration:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39442
diff changeset
301 return default