-
Notifications
You must be signed in to change notification settings - Fork 0
/
css2xpath.py
executable file
·66 lines (55 loc) · 1.5 KB
/
css2xpath.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#!/usr/bin/env python3
from io import StringIO
import re
import sys
def tok2nodetest(tok, write):
m = re.match('\\w+', tok)
if m is None:
write('*')
return tok
write(m.group())
return tok[len(m.group()):]
def tok2predicate(tok, write):
predicates = (
(r'\.([\-\w_]+)', "[contains(@class, '{}')]"),
(r'#([\-\w_]+)', "[@id='{}']"),
(r':nth-child\((\d+)\)', '[{}]'),
(r'():first', '{}[1]')
)
for regexp, fmt in predicates:
m = re.match(regexp, tok)
if m:
write(fmt.format(m.group(1)))
return tok[len(m.group()):]
raise Exception('Unknown predicate token: {}'.format(tok))
def transform(sel):
'Transform a css selector to xpath query string'
buf = StringIO()
tokens = sel.split()
if not tokens:
return ''
direct = False
for token in tokens:
if token == '>':
direct = True
else:
axis, direct = '/' if direct else '//', False
buf.write(axis)
token = tok2nodetest(token, buf.write)
while token:
token = tok2predicate(token, buf.write)
return buf.getvalue()
def main():
if len(sys.argv) > 1:
for sel in sys.argv[1:]:
print(transform(sel))
else:
while 1:
try:
sel = input()
except EOFError:
break
else:
print(transform(sel))
if __name__ == '__main__':
main()