Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions utils/xpath/xpath.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,17 @@ import (
)

var (
idPattern = `[a-zA-Z_][a-zA-Z\d\_\-\.]*`
idPattern = `[a-zA-Z_][a-zA-Z\d\_\-\.]*`
nodeIdPattern = `(?:` + idPattern + `:)?` + idPattern
// YANG identifiers must follow RFC 6020:
// https://tools.ietf.org/html/rfc6020#section-6.2.
idRe = regexp.MustCompile(`^(?:`+idPattern+`:)?` + idPattern + `$`)
idRe = regexp.MustCompile(`^` + nodeIdPattern + `$`)
// The sting representation of List key value pairs must follow the
// following pattern: [key=value], where key is the List key leaf name,
// and value is the string representation of key leaf value.
kvRe = regexp.MustCompile(`^\[` +
// Key leaf name must be a valid YANG identifier.
idPattern + `=` +
nodeIdPattern + `=` +
// Key leaf value must be a non-empty string, which may contain
// newlines. Use (?s) to turn on s flag to match newlines.
`((?s).+)` +
Expand Down
15 changes: 15 additions & 0 deletions utils/xpath/xpath_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,11 @@ func TestParseElement(t *testing.T) {
elem: "a[k1=v1][k2=v2]",
expectOK: true,
want: []interface{}{"a", map[string]string{"k1": "v1", "k2": "v2"}},
}, {
desc: "test list with xpath expression in key",
elem: "interface[name=current()]",
expectOK: true,
want: []interface{}{"interface", map[string]string{"name": "current()"}},
}}

for _, test := range tests {
Expand Down Expand Up @@ -360,6 +365,16 @@ func TestParseStringPath(t *testing.T) {
}, {
desc: "test path containing a multi-key List, second key-value pair without [ and ]",
path: "/a/b[k1=10]k2=abc/c",
}, {
desc: "test path containing prefix",
path: "/openconfig-interfaces:interface",
expectOK: true,
want: []interface{}{"openconfig-interfaces:interface"},
}, {
desc: "test path containing prefix in path and List",
path: "/oc-if:interfaces/oc-if:interface[oc-if:name=current()/../interface]/oc-if:subinterfaces",
expectOK: true,
want: []interface{}{"oc-if:interfaces", "oc-if:interface", map[string]string{"oc-if:name": "current()/../interface"}, "oc-if:subinterfaces"},
}}

for _, test := range tests {
Expand Down