Home | Trees | Indices | Help |
|
---|
|
1 # 2 # ElementTree 3 # $Id: ElementPath.py 3276 2007-09-12 06:52:30Z fredrik $ 4 # 5 # limited xpath support for element trees 6 # 7 # history: 8 # 2003-05-23 fl created 9 # 2003-05-28 fl added support for // etc 10 # 2003-08-27 fl fixed parsing of periods in element names 11 # 2007-09-10 fl new selection engine 12 # 13 # Copyright (c) 2003-2007 by Fredrik Lundh. All rights reserved. 14 # 15 # fredrik@pythonware.com 16 # http://www.pythonware.com 17 # 18 # -------------------------------------------------------------------- 19 # The ElementTree toolkit is 20 # 21 # Copyright (c) 1999-2007 by Fredrik Lundh 22 # 23 # By obtaining, using, and/or copying this software and/or its 24 # associated documentation, you agree that you have read, understood, 25 # and will comply with the following terms and conditions: 26 # 27 # Permission to use, copy, modify, and distribute this software and 28 # its associated documentation for any purpose and without fee is 29 # hereby granted, provided that the above copyright notice appears in 30 # all copies, and that both that copyright notice and this permission 31 # notice appear in supporting documentation, and that the name of 32 # Secret Labs AB or the author not be used in advertising or publicity 33 # pertaining to distribution of the software without specific, written 34 # prior permission. 35 # 36 # SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD 37 # TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- 38 # ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR 39 # BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY 40 # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 41 # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 42 # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 43 # OF THIS SOFTWARE. 44 # -------------------------------------------------------------------- 45 46 ## 47 # Implementation module for XPath support. There's usually no reason 48 # to import this module directly; the <b>ElementTree</b> does this for 49 # you, if needed. 50 ## 51 52 import re 53 54 xpath_tokenizer = re.compile( 55 "(" 56 "'[^']*'|\"[^\"]*\"|" 57 "::|" 58 "//?|" 59 "\.\.|" 60 "\(\)|" 61 "[/.*:\[\]\(\)@=])|" 62 "((?:\{[^}]+\})?[^/:\[\]\(\)@=\s]+)|" 63 "\s+" 64 ).findall 6567 tag = token[1] 68 def select(result): 69 for elem in result: 70 for e in elem.iterchildren(tag=tag): 71 yield e72 return select 73 79 return select 80 84 return select 8587 token = next() 88 if token[0] == "*": 89 tag = "*" 90 elif not token[0]: 91 tag = token[1] 92 else: 93 raise SyntaxError 94 def select(result): 95 for elem in result: 96 for e in elem.iterdescendants(tag=tag): 97 yield e98 return select 99101 def select(result): 102 for elem in result: 103 parent = elem.getparent() 104 if parent is not None: 105 yield parent106 return select 107109 # this one should probably be refactored... 110 token = next() 111 if token[0] == "@": 112 # attribute 113 token = next() 114 if token[0]: 115 raise SyntaxError("invalid attribute predicate") 116 key = token[1] 117 token = next() 118 if token[0] == "]": 119 def select(result): 120 for elem in result: 121 if elem.get(key) is not None: 122 yield elem123 elif token[0] == "=": 124 value = next()[0] 125 if value[:1] == "'" or value[:1] == '"': 126 value = value[1:-1] 127 else: 128 raise SyntaxError("invalid comparison target") 129 token = next() 130 def select(result): 131 for elem in result: 132 if elem.get(key) == value: 133 yield elem 134 if token[0] != "]": 135 raise SyntaxError("invalid attribute predicate") 136 elif not token[0]: 137 tag = token[1] 138 token = next() 139 if token[0] != "]": 140 raise SyntaxError("invalid node predicate") 141 def select(result): 142 for elem in result: 143 try: 144 elem.iterdescendants(tag).next() 145 yield elem 146 except StopIteration: 147 pass 148 else: 149 raise SyntaxError("invalid predicate") 150 return select 151 152 ops = { 153 "": prepare_tag, 154 "*": prepare_star, 155 ".": prepare_dot, 156 "..": prepare_dot_dot, 157 "//": prepare_iter, 158 "[": prepare_predicate, 159 } 160 161 _cache = {} 162 163 # -------------------------------------------------------------------- 164166 # compile selector pattern 167 try: 168 return _cache[path] 169 except KeyError: 170 pass 171 if len(_cache) > 100: 172 _cache.clear() 173 174 if path[:1] == "/": 175 raise SyntaxError("cannot use absolute path on element") 176 stream = iter(xpath_tokenizer(path)) 177 next = stream.next; token = next() 178 selector = [] 179 while 1: 180 try: 181 selector.append(ops[token[0]](next, token)) 182 except StopIteration: 183 raise SyntaxError("invalid path") 184 try: 185 token = next() 186 if token[0] == "/": 187 token = next() 188 except StopIteration: 189 break 190 return selector191 192 ## 193 # Iterate over the matching nodes 194196 # execute selector pattern 197 selector = _build_path_iterator(path) 198 result = iter((elem,)) 199 for select in selector: 200 result = select(result) 201 return result202 203 ## 204 # Find first matching object. 205 211 212 ## 213 # Find all matching objects. 214 217 218 ## 219 # Find text for first matching object. 220 227
Home | Trees | Indices | Help |
|
---|
Generated by Epydoc 3.0beta1 on Sun Jan 27 09:00:40 2008 | http://epydoc.sourceforge.net |