summaryrefslogtreecommitdiffstats
path: root/tools/lib/xpath.py
blob: 07f8e389e028f553da056d588efb8b46487cd562 (plain)
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import re


class XPathComponent:
    regex = r"([^\/^\[]+)(\[([^\]]+)\])?"
    def __init__(self, expr):
        matches = re.finditer(XPathComponent.regex, expr, re.DOTALL | re.IGNORECASE)
        match = next(matches)
        self.name = match.group(1)
        tmp = match.group(3) if len(match.groups())>2 else None
        self.filter = tmp.split(',') if tmp is not None else [] 

    def equals(self, comp, ignoreFilter=False) -> bool:
        if ignoreFilter:
            return self.name == comp.name
        if self.name == comp.name:
            return set(self.filter) == set(comp.filter)
        return False
    
    def setFilter(self, f, v):
        self.filter.append('{}={}'.format(f,v))

    def hasFilter(self, propertyName):
        search=propertyName+'='
        for filter in self.filter:
            if filter.startswith(search):
                return True
        return False

    def __str__(self) -> str:
        return "XPathComponent[name={}, filter={}]".format(self.name, self.filter)
    
class XPath:

    def __init__(self, expr=None):
        self.raw = expr
        tmp = expr.split('/') if expr is not None else []
        self.components=[]
        if len(tmp)>0 and len(tmp[0])==0:
            tmp.pop(0)
        for x in tmp:
            self.components.append(XPathComponent(x))
    
    def add(self, c: str) -> XPathComponent:
        xc=XPathComponent(c)
        self.components.append(xc)
        return xc

    def remove(self, c: str) -> bool:
        if self.components[len(self.components)-1].equals(XPathComponent(c), True):
            self.components.pop()
            return True
        return False

    def parentParamIsNeeded(self, xp, paramName) -> bool:
        for i in range(len(xp.components)):
            if i>=len(self.components):
                return False
            if not self.components[i].equals(xp.components[i], True):
                return False
        return self.components[len(xp.components)-1].hasFilter(paramName)

    def equals(self, path, ignoreFilter=False) -> bool:
        if len(self.components) != len(path.components):
            return False

        for i in range(len(self.components)):
            if not self.components[i].equals(path.components[i], ignoreFilter):
                return False
        return True

    def lastname(self) -> str:
        tmp = self.last()
        return tmp.name if tmp is not None else ""

    def last(self, off=0) -> XPathComponent:
        return self.components[len(self.components)-1-off] if len(self.components)>off else None

    def subpath(self, off=0):
        tmp =XPath()
        for i in range(len(self.components)-off):
            tmp.components.append(self.components[i])
        return tmp