はじめに
NSO では yang model のデータにアクセスするために様々な場面で XPath を使用します。例えば、以下のような場面で使用します。
- yang model 内の leafref/must/when など
- config template
- サービスモデルの Java/Python コード
- REST API や NETCONF northbound interface でのクエリ
NSO では XPath 1.0 をサポートしていますので、より詳しい情報は以下のリンクを参照してみてください。
XML Path Language (XPath) Version 1.0
https://www.w3.org/TR/xpath/
また、NSO では独自の拡張機能が実装されています。より詳細は man tailf_yang_extensions に含まれている XPATH FUNCTIONS セクションを参照してください。
本ドキュメントでは、XPath の基本的なサンプルをいくつか紹介していきたいと思います。また、確認用のツールとして NSO CLI の xpath コマンドを使用していますので、こちらの詳細については以下のドキュメントを参照ください。
NSO: CLI の便利なツール - devtools
https://supportforums.cisco.com/ja/document/13286076
要素へのアクセス
例えば以下のようなデータがあるとします。
devices device router0 address 127.0.0.1 port 10022 device-type cli ned-id cisco-ios devices device router1 address 127.0.0.1 port 10023 device-type cli ned-id cisco-ios
|
デバイスの name にアクセスする場合は以下のように記載することができます。
admin@ncs(config)# xpath eval /devices/device/name /ncs:devices/ncs:device[ncs:name='router1']/ncs:name :: router1 /ncs:devices/ncs:device[ncs:name='router0']/ncs:name :: router0
|
上の例では Root(/) からの絶対パスで指定していますが、現在の XPath コンテキストから相対パスで指定することもできます。
admin@ncs(config)# devices device router0 admin@ncs(config-device-router0)# xpath eval ./name /ncs:devices/ncs:device[ncs:name='router0']/ncs:name :: router0
admin@ncs(config-device-router0)# xpath eval ../device[name='router1']/port /ncs:devices/ncs:device[ncs:name='router1']/ncs:port :: 10023 |
// を使用することで途中のパスを省略することもできます。
admin@ncs(config)# xpath eval /devices//ned-id /ncs:devices/ncs:device[ncs:name='router1']/ncs:device-type/ncs:cli/ncs:ned-id :: cisco-ios /ncs:devices/ncs:device[ncs:name='router0']/ncs:device-type/ncs:cli/ncs:ned-id :: cisco-ios
|
ノードの属性(attribute) にアクセスするには @ を使用します。router0 が以下のような annotation を持っているとします。
@ を使用して以下のように annotation 属性にアクセスできます。
admin@ncs(config)# xpath eval /devices/device/@annotation /ncs:devices/ncs:device[ncs:name='router0'] :: testannotate |
評価
Xpath では値を評価する際に以下の表現が使用できます。
admin@ncs(config-device-router0)# xpath eval "./name='router0' and ./address='127.0.0.1'" true
admin@ncs(config-device-router0)# xpath eval "./name='router1' or ./address='127.0.0.1'" true admin@ncs(config-device-router0)# xpath eval count(./config/ios:interface/FastEthernet) 4 admin@ncs(config-device-router0)# xpath eval count(./config/ios:interface/FastEthernet)>3 true admin@ncs(config-device-router0)# xpath eval count(./config/ios:interface/FastEthernet)>5 admin@ncs(config-device-router0)# admin@ncs(config-device-router0)# xpath eval count(./config/ios:interface/FastEthernet)>=4 true |
Core function
XPath 1.0 に記載されている Core function が使用できます。詳しくは上述の XPath 1.0 のドキュメントを参照ください。以下によく使用される function をいくつか記載します。
count() - ノードの個数を返します。
admin@ncs(config)# xpath eval count(/devices/device[name='router0']/config/ios:interface/FastEthernet) 4
|
cotains() - ノードの値に指定の文字列が含まれている場合 true を返します。
admin@ncs(config-device-router0)# xpath eval contains(./address, '127') true |
starts-with() - ノードの値が指定の文字列で始まる場合 true を返します。
admin@ncs(config-device-router0)# xpath eval starts-with(./name,'router') true admin@ncs(config-device-router0)# xpath eval starts-with(./name,'routers') false |
not() - 引数が false の場合 true を返します。
admin@ncs(config-device-router0)# xpath eval starts-with(./name,'router') true admin@ncs(config-device-router0)# xpath eval starts-with(./name,'routers') false |
position() - コンテキストの position を数字で返します。
admin@ncs(config)# xpath eval /devices/device[position()=1] /ncs:devices/ncs:device[ncs:name='router0'] admin@ncs(config)# xpath eval /devices/device[position()=2] /ncs:devices/ncs:device[ncs:name='router1'] |
NSO Extention
XPath 1.0 の Core function に加え、NSO で独自に拡張した function を使用することができます。使用できる function のリストについては man tailf_yang_extensions に含まれている XPATH FUNCTIONS セクションを参照してください。以下にいくつかサンプルを記載します。
re-match() - 第 1 引数の値が第 2 引数の regular expression にマッチする場合に true を返します。
admin@ncs(config-device-router1)# xpath eval re-match(./name,'.*0') false admin@ncs(config-device-router1)# xpath eval re-match(./name,'.*1') true
|
マニュアルにも記載されていますが、implicit anchoring が適用される点に注意してください。上述の例は最後の文字を対象にしていますが、通常の regular expression のように最後に $ を付けてしまうと true になりません。
max() - 一番大きい数字を返します。
admin@ncs(config)# xpath eval max(/devices/device/port) 10023
|
実際にはさらに複雑な XPath が多く使われています。興味がある方は NSO や NED に含まれている yang ファイルの中身を一度見てみると面白いかもしれません。