ToineSiebelink | 98c0787 | 2021-04-20 17:33:09 +0100 | [diff] [blame] | 1 | .. This work is licensed under a Creative Commons Attribution 4.0 International License. |
| 2 | .. http://creativecommons.org/licenses/by/4.0 |
danielhanrahan | e05a59a | 2023-06-23 14:37:12 +0100 | [diff] [blame] | 3 | .. Copyright (C) 2021-2023 Nordix Foundation |
Rudrangi Anupriya | c58a0f4 | 2023-04-25 13:13:16 +0530 | [diff] [blame] | 4 | .. Modifications Copyright (C) 2023 TechMahindra Ltd |
ToineSiebelink | 98c0787 | 2021-04-20 17:33:09 +0100 | [diff] [blame] | 5 | |
| 6 | .. DO NOT CHANGE THIS LABEL FOR RELEASE NOTES - EVEN THOUGH IT GIVES A WARNING |
emaclee | b176de2 | 2022-08-31 15:53:10 +0100 | [diff] [blame] | 7 | .. _path: |
ToineSiebelink | 98c0787 | 2021-04-20 17:33:09 +0100 | [diff] [blame] | 8 | |
| 9 | |
| 10 | CPS Path |
| 11 | ######## |
| 12 | |
| 13 | .. toctree:: |
| 14 | :maxdepth: 1 |
| 15 | |
| 16 | Introduction |
| 17 | ============ |
| 18 | |
ToineSiebelink | f0527c5 | 2021-07-06 13:03:03 +0100 | [diff] [blame] | 19 | Several CPS APIs use the CPS path (or cpsPath in Java API) parameter. |
| 20 | The CPS path parameter is used for querying xpaths. CPS path is inspired by the `XML Path Language (XPath) 3.1. <https://www.w3.org/TR/2017/REC-xpath-31-20170321/>`_ |
ToineSiebelink | 98c0787 | 2021-04-20 17:33:09 +0100 | [diff] [blame] | 21 | |
| 22 | This section describes the functionality currently supported by CPS Path. |
| 23 | |
Lathish | b3550f1 | 2022-03-15 12:03:53 +0000 | [diff] [blame] | 24 | Sample Yang Model |
| 25 | ================= |
ToineSiebelink | 98c0787 | 2021-04-20 17:33:09 +0100 | [diff] [blame] | 26 | |
Lathish | b3550f1 | 2022-03-15 12:03:53 +0000 | [diff] [blame] | 27 | .. code-block:: |
| 28 | |
| 29 | module stores { |
| 30 | yang-version 1.1; |
| 31 | namespace "org:onap:ccsdk:sample"; |
| 32 | |
| 33 | prefix book-store; |
| 34 | |
| 35 | revision "2020-09-15" { |
| 36 | description |
| 37 | "Sample Model"; |
| 38 | } |
| 39 | container shops { |
| 40 | |
| 41 | container bookstore { |
| 42 | |
| 43 | leaf bookstore-name { |
| 44 | type string; |
| 45 | } |
| 46 | |
| 47 | leaf name { |
| 48 | type string; |
| 49 | } |
| 50 | |
| 51 | list categories { |
| 52 | |
| 53 | key "code"; |
| 54 | |
| 55 | leaf code { |
| 56 | type uint16; |
| 57 | } |
| 58 | |
| 59 | leaf name { |
| 60 | type string; |
| 61 | } |
| 62 | |
| 63 | leaf numberOfBooks { |
| 64 | type uint16; |
| 65 | } |
| 66 | |
| 67 | container books { |
| 68 | |
| 69 | list book { |
| 70 | key title; |
| 71 | |
| 72 | leaf title { |
| 73 | type string; |
| 74 | } |
| 75 | leaf price { |
| 76 | type uint16; |
| 77 | } |
| 78 | leaf-list label { |
| 79 | type string; |
| 80 | } |
| 81 | leaf-list edition { |
| 82 | type string; |
| 83 | } |
| 84 | } |
| 85 | } |
| 86 | } |
| 87 | } |
| 88 | } |
| 89 | } |
| 90 | |
| 91 | **Note.** 'categories' is a Yang List and 'code' is its key leaf. All other data nodes are Yang Containers. 'label' and 'edition' are both leaf-lists. |
| 92 | |
| 93 | **Note.** CPS accepts only json data. The xml data presented here is for illustration purposes only. |
| 94 | |
| 95 | The json and xml below describes some basic data to be used to illustrate the CPS Path functionality. |
| 96 | |
| 97 | Sample Data in Json |
| 98 | =================== |
| 99 | |
| 100 | .. code-block:: json |
| 101 | |
| 102 | { |
| 103 | "shops": { |
| 104 | "bookstore": { |
| 105 | "bookstore-name": "Chapters", |
| 106 | "name": "Chapters", |
| 107 | "categories": [ |
| 108 | { |
| 109 | "code": 1, |
| 110 | "name": "SciFi", |
| 111 | "numberOfBooks": 2, |
| 112 | "books": { |
| 113 | "book": [ |
| 114 | { |
| 115 | "title": "2001: A Space Odyssey", |
| 116 | "price": 5, |
| 117 | "label": ["sale", "classic"], |
| 118 | "edition": ["1968", "2018"] |
| 119 | }, |
| 120 | { |
| 121 | "title": "Dune", |
| 122 | "price": 5, |
| 123 | "label": ["classic"], |
| 124 | "edition": ["1965"] |
| 125 | } |
| 126 | ] |
| 127 | } |
| 128 | }, |
| 129 | { |
| 130 | "code": 2, |
| 131 | "name": "Kids", |
| 132 | "numberOfBooks": 1, |
| 133 | "books": { |
| 134 | "book": [ |
| 135 | { |
| 136 | "title": "Matilda" |
| 137 | } |
| 138 | ] |
| 139 | } |
| 140 | } |
| 141 | ] |
| 142 | } |
| 143 | } |
| 144 | } |
| 145 | |
| 146 | Sample Data in XML |
| 147 | ================== |
ToineSiebelink | 98c0787 | 2021-04-20 17:33:09 +0100 | [diff] [blame] | 148 | |
| 149 | .. code-block:: xml |
| 150 | |
| 151 | <shops> |
| 152 | <bookstore name="Chapters"> |
ToineSiebelink | f0527c5 | 2021-07-06 13:03:03 +0100 | [diff] [blame] | 153 | <bookstore-name>Chapters</bookstore-name> |
Lathish | b3550f1 | 2022-03-15 12:03:53 +0000 | [diff] [blame] | 154 | <categories code=1 name="SciFi" numberOfBooks="2"> |
ToineSiebelink | f0527c5 | 2021-07-06 13:03:03 +0100 | [diff] [blame] | 155 | <books> |
| 156 | <book title="2001: A Space Odyssey" price="5"> |
| 157 | <label>sale</label> |
| 158 | <label>classic</label> |
| 159 | <edition>1968</edition> |
| 160 | <edition>2018</edition> |
| 161 | </book> |
| 162 | <book title="Dune" price="5"> |
| 163 | <label>classic</label> |
| 164 | <edition>1965</edition> |
| 165 | </book> |
| 166 | </books> |
| 167 | </categories> |
Lathish | b3550f1 | 2022-03-15 12:03:53 +0000 | [diff] [blame] | 168 | <categories code=2 name="Kids" numberOfBooks="1"> |
ToineSiebelink | f0527c5 | 2021-07-06 13:03:03 +0100 | [diff] [blame] | 169 | <books> |
| 170 | <book title="Matilda" /> |
| 171 | </books> |
| 172 | </categories> |
ToineSiebelink | 98c0787 | 2021-04-20 17:33:09 +0100 | [diff] [blame] | 173 | </bookstore> |
| 174 | </shops> |
| 175 | |
ToineSiebelink | 98c0787 | 2021-04-20 17:33:09 +0100 | [diff] [blame] | 176 | General Notes |
| 177 | ============= |
| 178 | |
ToineSiebelink | f0527c5 | 2021-07-06 13:03:03 +0100 | [diff] [blame] | 179 | - String values must be wrapped in quotation marks ``"`` (U+0022) or apostrophes ``'`` (U+0027). |
ToineSiebelink | 98c0787 | 2021-04-20 17:33:09 +0100 | [diff] [blame] | 180 | - String comparisons are case sensitive. |
| 181 | |
ToineSiebelink | f0527c5 | 2021-07-06 13:03:03 +0100 | [diff] [blame] | 182 | Query Syntax |
| 183 | ============ |
ToineSiebelink | 98c0787 | 2021-04-20 17:33:09 +0100 | [diff] [blame] | 184 | |
Rudrangi Anupriya | 94b5c8a | 2023-04-27 12:04:52 +0530 | [diff] [blame] | 185 | ``( <absolute-path> | <descendant-path> ) [ <leaf-conditions> ] [ <text()-condition> ] [ <contains()-condition> ] [ <ancestor-axis> ]`` |
ToineSiebelink | 98c0787 | 2021-04-20 17:33:09 +0100 | [diff] [blame] | 186 | |
ToineSiebelink | f0527c5 | 2021-07-06 13:03:03 +0100 | [diff] [blame] | 187 | Each CPS path expression need to start with an 'absolute' or 'descendant' xpath. |
| 188 | |
| 189 | absolute-path |
| 190 | ------------- |
| 191 | |
| 192 | **Syntax**: ``'/' <container-name> ( '[' <list-key> ']' )? ( '/' <containerName> ( '[' <list-key> ']' )? )*`` |
| 193 | |
| 194 | - ``container name``: Any yang container or list. |
| 195 | - ``list-key``: One or more key-value pairs, each preceded by the ``@`` symbol, combined using the ``and`` keyword. |
| 196 | - The above van repeated any number of times. |
| 197 | |
| 198 | **Examples** |
| 199 | - ``/shops/bookstore`` |
Lathish | b3550f1 | 2022-03-15 12:03:53 +0000 | [diff] [blame] | 200 | - ``/shops/bookstore/categories[@code='1']/books`` |
| 201 | - ``/shops/bookstore/categories[@code='1']/books/book[@title='2001: A Space Odyssey']`` |
ToineSiebelink | f0527c5 | 2021-07-06 13:03:03 +0100 | [diff] [blame] | 202 | |
| 203 | **Limitations** |
| 204 | - Absolute paths must start with the top element (data node) as per the model tree. |
| 205 | - Each list reference must include a valid instance reference to the key for that list. Except when it is the last element. |
| 206 | |
| 207 | descendant-path |
| 208 | --------------- |
| 209 | |
| 210 | **Syntax**: ``'//' <container-name> ( '[' <list-key> ']' )? ( '/' <containerName> ( '[' <list-key> ']' )? )*`` |
| 211 | |
| 212 | - The syntax of a descendant path is identical to a absolute path except that it is preceded by a double slash ``//``. |
| 213 | |
| 214 | **Examples** |
| 215 | - ``//bookstore`` |
Lathish | b3550f1 | 2022-03-15 12:03:53 +0000 | [diff] [blame] | 216 | - ``//categories[@code='1']/books`` |
ToineSiebelink | f0527c5 | 2021-07-06 13:03:03 +0100 | [diff] [blame] | 217 | - ``//bookstore/categories`` |
| 218 | |
| 219 | **Limitations** |
| 220 | - Each list reference must include a valid instance reference to the key for that list. Except when it is the last element. |
| 221 | |
| 222 | leaf-conditions |
| 223 | --------------- |
| 224 | |
Rudrangi Anupriya | b622c58 | 2023-05-31 21:33:32 +0530 | [diff] [blame] | 225 | **Syntax**: ``<xpath> '[' @<leaf-name1> '(=|>|<|>=|<=)' <leaf-value1> ( ' <and|or> ' @<leaf-name> '(=|>|<|>=|<=)' <leaf-value> )* ']'`` |
ToineSiebelink | f0527c5 | 2021-07-06 13:03:03 +0100 | [diff] [blame] | 226 | - ``xpath``: Absolute or descendant or xpath to the (list) node which elements will be queried. |
ToineSiebelink | 98c0787 | 2021-04-20 17:33:09 +0100 | [diff] [blame] | 227 | - ``leaf-name``: The name of the leaf which value needs to be compared. |
| 228 | - ``leaf-value``: The required value of the leaf. |
| 229 | |
| 230 | **Examples** |
| 231 | - ``/shops/bookstore/categories[@numberOfBooks=1]`` |
ToineSiebelink | f0527c5 | 2021-07-06 13:03:03 +0100 | [diff] [blame] | 232 | - ``//categories[@name="Kids"]`` |
| 233 | - ``//categories[@name='Kids']`` |
Lathish | b3550f1 | 2022-03-15 12:03:53 +0000 | [diff] [blame] | 234 | - ``//categories[@code='1']/books/book[@title='Dune' and @price=5]`` |
Rudrangi Anupriya | c58a0f4 | 2023-04-25 13:13:16 +0530 | [diff] [blame] | 235 | - ``//categories[@code='1']/books/book[@title='xyz' or @price=15]`` |
Rudrangi Anupriya | b622c58 | 2023-05-31 21:33:32 +0530 | [diff] [blame] | 236 | - ``//categories[@code='1']/books/book[@title='xyz' or @price>20]`` |
| 237 | - ``//categories[@code='1']/books/book[@title='Dune' and @price<=5]`` |
Lathish | a7dc916 | 2022-04-28 16:37:00 +0100 | [diff] [blame] | 238 | - ``//categories[@code=1]`` |
ToineSiebelink | 98c0787 | 2021-04-20 17:33:09 +0100 | [diff] [blame] | 239 | **Limitations** |
ToineSiebelink | f0527c5 | 2021-07-06 13:03:03 +0100 | [diff] [blame] | 240 | - Only the last list or container can be queried leaf values. Any ancestor list will have to be referenced by its key name-value pair(s). |
Rudrangi Anupriya | c58a0f4 | 2023-04-25 13:13:16 +0530 | [diff] [blame] | 241 | - When mixing ``and/or`` operators, ``and`` has precedence over ``or`` . So ``and`` operators get evaluated first. |
| 242 | - Bracketing is not supported. |
| 243 | - Leaf names are not validated so ``or`` operations with invalid leaf names will silently be ignored. |
ToineSiebelink | f0527c5 | 2021-07-06 13:03:03 +0100 | [diff] [blame] | 244 | - Only leaves can be used, leaf-list are not supported. |
| 245 | - Only string and integer values are supported, boolean and float values are not supported. |
Rudrangi Anupriya | b622c58 | 2023-05-31 21:33:32 +0530 | [diff] [blame] | 246 | - Using comparative operators with string values will lead to an error at runtime. This error can't be validated earlier as the datatype is unknown until the execution phase. |
Lathish | a7dc916 | 2022-04-28 16:37:00 +0100 | [diff] [blame] | 247 | - The key should be supplied with correct data type for it to be queried from DB. In the last example above the attribute code is of type |
| 248 | Integer so the cps query will not work if the value is passed as string. |
| 249 | eg: ``//categories[@code="1"]`` or ``//categories[@code='1']`` will not work because the key attribute code is treated a string. |
puthuparambil.aditya | dd90432 | 2022-09-21 10:53:51 +0100 | [diff] [blame] | 250 | - Having '[' token in any index in any list will have a negative impact on this function. |
ToineSiebelink | 98c0787 | 2021-04-20 17:33:09 +0100 | [diff] [blame] | 251 | |
| 252 | **Notes** |
puthuparambil.aditya | 0531607 | 2021-04-23 12:52:09 +0100 | [diff] [blame] | 253 | - For performance reasons it does not make sense to query using key leaf as attribute. If the key value is known it is better to execute a get request with the complete xpath. |
ToineSiebelink | 98c0787 | 2021-04-20 17:33:09 +0100 | [diff] [blame] | 254 | |
ToineSiebelink | f0527c5 | 2021-07-06 13:03:03 +0100 | [diff] [blame] | 255 | text()-condition |
| 256 | ---------------- |
ToineSiebelink | 98c0787 | 2021-04-20 17:33:09 +0100 | [diff] [blame] | 257 | |
ToineSiebelink | f0527c5 | 2021-07-06 13:03:03 +0100 | [diff] [blame] | 258 | The text()-condition can be added to any CPS path query. |
| 259 | |
| 260 | **Syntax**: ``<cps-path> ( '/' <leaf-name> '[text()=' <string-value> ']' )?`` |
| 261 | - ``cps-path``: Any CPS path query. |
| 262 | - ``leaf-name``: The name of the leaf or leaf-list which value needs to be compared. |
| 263 | - ``string-value``: The required value of the leaf or leaf-list element as a string wrapped in quotation marks (U+0022) or apostrophes (U+0027). This wil still match integer values. |
ToineSiebelink | 98c0787 | 2021-04-20 17:33:09 +0100 | [diff] [blame] | 264 | |
| 265 | **Examples** |
ToineSiebelink | f0527c5 | 2021-07-06 13:03:03 +0100 | [diff] [blame] | 266 | - ``//book/label[text()="classic"]`` |
| 267 | - ``//book/edition[text()="1965"]`` |
ToineSiebelink | 98c0787 | 2021-04-20 17:33:09 +0100 | [diff] [blame] | 268 | |
| 269 | **Limitations** |
ToineSiebelink | f0527c5 | 2021-07-06 13:03:03 +0100 | [diff] [blame] | 270 | - Only the last list or container can be queried for leaf values with a text() condition. Any ancestor list will have to be referenced by its key name-value pair(s). |
| 271 | - Only one leaf or leaf-list can be tested. |
| 272 | - Only string and integer values are supported, boolean and float values are not supported. |
| 273 | - Since CPS cannot return individual leaves it will always return the container with all its leaves. Ancestor-axis can be used to specify a parent higher up the tree. |
| 274 | - When querying a leaf value (instead of leaf-list) it is better, more performant to use a text value condition use @<leaf-name> as described above. |
puthuparambil.aditya | dd90432 | 2022-09-21 10:53:51 +0100 | [diff] [blame] | 275 | - Having '[' token in any index in any list will have a negative impact on this function. |
puthuparambil.aditya | ff71462 | 2021-04-23 11:55:24 +0100 | [diff] [blame] | 276 | |
Rudrangi Anupriya | 94b5c8a | 2023-04-27 12:04:52 +0530 | [diff] [blame] | 277 | contains()-condition |
| 278 | -------------------- |
| 279 | |
| 280 | **Syntax**: ``<cps-path> '[' 'contains' '(' '<leaf-name>','<string-value>' ')' ']'?`` |
| 281 | - ``cps-path``: Any CPS path query. |
| 282 | - ``leaf-name``: The name of the leaf which value needs to be compared. |
| 283 | - ``string-value``: The required value of the leaf element as a string wrapped in quotation marks (U+0022) or apostrophes (U+0027). This will still match integer values. |
| 284 | |
| 285 | **Examples** |
| 286 | - ``//categories[contains(@name,'Sci')]`` |
| 287 | - ``//books[contains(@title,'Space')]`` |
| 288 | |
| 289 | **Limitations** |
| 290 | - Only leaves can be used, leaf-list are not supported. |
| 291 | - Leaf names are not validated so ``contains() condition`` with invalid leaf names will silently be ignored. |
| 292 | |
| 293 | **Notes** |
| 294 | - contains condition is case sensitive. |
| 295 | |
ToineSiebelink | f0527c5 | 2021-07-06 13:03:03 +0100 | [diff] [blame] | 296 | ancestor-axis |
niamhcore | 4395c1f | 2021-05-05 11:42:20 +0100 | [diff] [blame] | 297 | ------------- |
| 298 | |
ToineSiebelink | f0527c5 | 2021-07-06 13:03:03 +0100 | [diff] [blame] | 299 | The ancestor axis can be added to any CPS path query but has to be the last part. |
niamhcore | 4395c1f | 2021-05-05 11:42:20 +0100 | [diff] [blame] | 300 | |
ToineSiebelink | f0527c5 | 2021-07-06 13:03:03 +0100 | [diff] [blame] | 301 | **Syntax**: ``<cps-path> ( '/ancestor::' <ancestor-path> )?`` |
niamhcore | 4395c1f | 2021-05-05 11:42:20 +0100 | [diff] [blame] | 302 | - ``cps-path``: Any CPS path query. |
ToineSiebelink | f0527c5 | 2021-07-06 13:03:03 +0100 | [diff] [blame] | 303 | - ``ancestor-path``: Partial path to ancestors of the target node. This can contain one or more ancestor nodes separated by a ``/``. |
niamhcore | 4395c1f | 2021-05-05 11:42:20 +0100 | [diff] [blame] | 304 | |
| 305 | **Examples** |
| 306 | - ``//book/ancestor::categories`` |
Lathish | b3550f1 | 2022-03-15 12:03:53 +0000 | [diff] [blame] | 307 | - ``//categories[@code='2']/books/ancestor::bookstore`` |
| 308 | - ``//book/ancestor::categories[@code='1']/books`` |
| 309 | - ``//book/label[text()="classic"]/ancestor::shops`` |
niamhcore | 4395c1f | 2021-05-05 11:42:20 +0100 | [diff] [blame] | 310 | |
| 311 | **Limitations** |
| 312 | - Ancestor list elements can only be addressed using the list key leaf. |
ToineSiebelink | f0527c5 | 2021-07-06 13:03:03 +0100 | [diff] [blame] | 313 | - List elements with compound keys are not supported. |