blob: 07f8e389e028f553da056d588efb8b46487cd562 [file] [log] [blame]
Michael DÜrre7bb133e2022-01-18 10:06:31 +01001
2import re
3
4
5class XPathComponent:
6 regex = r"([^\/^\[]+)(\[([^\]]+)\])?"
7 def __init__(self, expr):
8 matches = re.finditer(XPathComponent.regex, expr, re.DOTALL | re.IGNORECASE)
9 match = next(matches)
10 self.name = match.group(1)
11 tmp = match.group(3) if len(match.groups())>2 else None
12 self.filter = tmp.split(',') if tmp is not None else []
13
14 def equals(self, comp, ignoreFilter=False) -> bool:
15 if ignoreFilter:
16 return self.name == comp.name
17 if self.name == comp.name:
18 return set(self.filter) == set(comp.filter)
19 return False
20
21 def setFilter(self, f, v):
22 self.filter.append('{}={}'.format(f,v))
23
24 def hasFilter(self, propertyName):
25 search=propertyName+'='
26 for filter in self.filter:
27 if filter.startswith(search):
28 return True
29 return False
30
31 def __str__(self) -> str:
32 return "XPathComponent[name={}, filter={}]".format(self.name, self.filter)
33
34class XPath:
35
36 def __init__(self, expr=None):
37 self.raw = expr
38 tmp = expr.split('/') if expr is not None else []
39 self.components=[]
40 if len(tmp)>0 and len(tmp[0])==0:
41 tmp.pop(0)
42 for x in tmp:
43 self.components.append(XPathComponent(x))
44
45 def add(self, c: str) -> XPathComponent:
46 xc=XPathComponent(c)
47 self.components.append(xc)
48 return xc
49
50 def remove(self, c: str) -> bool:
51 if self.components[len(self.components)-1].equals(XPathComponent(c), True):
52 self.components.pop()
53 return True
54 return False
55
56 def parentParamIsNeeded(self, xp, paramName) -> bool:
57 for i in range(len(xp.components)):
58 if i>=len(self.components):
59 return False
60 if not self.components[i].equals(xp.components[i], True):
61 return False
62 return self.components[len(xp.components)-1].hasFilter(paramName)
63
64 def equals(self, path, ignoreFilter=False) -> bool:
65 if len(self.components) != len(path.components):
66 return False
67
68 for i in range(len(self.components)):
69 if not self.components[i].equals(path.components[i], ignoreFilter):
70 return False
71 return True
72
73 def lastname(self) -> str:
74 tmp = self.last()
75 return tmp.name if tmp is not None else ""
76
77 def last(self, off=0) -> XPathComponent:
78 return self.components[len(self.components)-1-off] if len(self.components)>off else None
79
80 def subpath(self, off=0):
81 tmp =XPath()
82 for i in range(len(self.components)-off):
83 tmp.components.append(self.components[i])
84 return tmp