-
Notifications
You must be signed in to change notification settings - Fork 0
/
path.go
95 lines (80 loc) · 2.01 KB
/
path.go
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
85
86
87
88
89
90
91
92
93
94
95
package bond
import (
"fmt"
"regexp"
"strings"
)
var (
ignoreKeysPattern = `\[.*?\]|(%s)`
)
// convertXPathToJSPath converts xp in XPath format to JSPath.
func convertXPathToJSPath(xp string) string {
if xp == "" {
return ""
}
p := replaceAllIgnoreKeys(xp, "/", ".")
// Replace [name=key] with {.name=="key"}; List nodes
var sb strings.Builder
sb.Grow(len(xp) + 10) // Pre-allocate some extra space for potential additions
for _, ch := range p {
switch ch {
case '[':
sb.WriteString("{.")
case ']':
sb.WriteString("\"}")
case '=':
sb.WriteString("==\"")
default:
sb.WriteRune(ch)
}
}
return sb.String()
}
// convertJSPathToXPath converts JSPath to xp in XPath format.
func convertJSPathToXPath(jsPath string) string {
if jsPath == "" {
return ""
}
p := replaceAllIgnoreKeys(jsPath, "_", "-")
// Replace {.name=="key"} with [name=key]; List nodes
var sb strings.Builder
sb.Grow(len(p) + 10) // Pre-allocate some extra space for potential additions
// Iterate two characters at a time
for i := 0; i < len(p)-1; i++ {
str := p[i : i+2]
switch str {
case "{.":
sb.WriteString("[")
i++
case "\"}":
sb.WriteString("]")
i++
case "==":
sb.WriteString("=")
i += 2 // skip \" char in "==\""
default:
sb.WriteByte(str[0])
// write last char if second to last index
if i == len(p)-2 {
sb.WriteByte(str[1])
}
}
}
return replaceAllIgnoreKeys(sb.String(), ".", "/")
}
// replaceAllIgnoreKeys replaces oldStr substring in path with newStr.
// list keys in brackets that contain oldStr are not replaced.
// e.g. /ndkDemo/list-node[ethernet-1/1], "/", "." -> .ndkDemo.list-node[ethernet-1/1]
func replaceAllIgnoreKeys(path, oldStr, newStr string) string {
// Compile the regex pattern
pattern := fmt.Sprintf(ignoreKeysPattern, regexp.QuoteMeta(oldStr))
re := regexp.MustCompile(pattern)
// Perform the replacement
result := re.ReplaceAllStringFunc(path, func(match string) string {
if match == oldStr {
return newStr
}
return match
})
return result
}