cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
1855
Views
5
Helpful
6
Replies

Can I use something like * in name leaf field for an xpath eval?

The below is a modification to the CDB that we use for if a command is supported or not by a device. I would like to perform an xpath eval on the below, without having to specify the interface, Vlan{1}, in the keypath. Is there a way that I can use a wildcard for part of the 'name' leaf in the xpath eval? I would like to use these lookups in my XML template, not just for viewing as I have shown below.

 

You can see that with the full 'name' leaf filled out I get a response back with one of the entries, but any attempt to use a wildcard, *, character fails.

 

admin@nso(config)# xpath eval /config-support[device-name='device1']/keypath[name='ios:interface/Vlan{1}/ipv6/flow/monitor{input}/name']
/config-support[device-name='device1']/keypath[name='ios:interface/Vlan{1}/ipv6/flow/monitor{input}/name']

 

admin@nso(config)# xpath eval /config-support[device-name='device1']/keypath[name='ios:interface/Vlan{*}/ipv6/flow/monitor{input}/name']

 

admin@nso(config)# xpath eval /config-support[device-name='device1']/keypath[name='ios:interface/Vlan/ipv6/flow/monitor{input}/name']

 

admin@nso(config)# xpath eval /config-support[device-name='device1']/keypath[name='ios:interface/*/ipv6/flow/monitor{input}/name']

 

Any thoughts on how I can have part of a leaf value in a xpath eval be wildcard?

1 Accepted Solution

Accepted Solutions

Okay, I don't think I knew about some of the xpath functions that existed. After seeing the starts-with, it looks like I can use that and a contains to accomplish what I'm after. Wish it was a little more direct, but this will work.

admin@nso(config)# xpath eval /config-support[device-name='device1']/keypath[starts-with(.,'ios:interface/Vlan')][contains(.,'/ipv6/flow/monitor{input}/name']
/config-support[device-name='device1']/keypath[name='ios:interface/Vlan{1}/ipv6/flow/monitor{input}/name']
/config-support[device-name='device1']/keypath[name='ios:interface/Vlan{1}/ipv6/flow/monitor{output}/name']

View solution in original post

6 Replies 6

vleijon
Cisco Employee
Cisco Employee
You can just omit the filter. For instance xpath eval /devices/device/device-type gives you the type of all devices.

I know that I can omit the filter, but there are other 'name's, such as 'ios:flow/record', 'ios:flow/exporter', etc.

I would like to just grab all of the ones with interface in the text, or a specific interface type. I know that for just doing an xpath eval I could do a `| include interface` to help accomplish this, however I am using these xpath lookups in my XML template in an <?if?> statement to see if the command is supported or not, so I am unable to use the pipe command.

Example from the XML template:
<?if {not(/config-support[device-name=$DEVICE_NAME]/keypath[name="ios:flow/record\{DISCOVERY-UNUSED-RECORD\}/collect/datalink/mac/source/address/input"]/support = 'false')}?>
<input/>
<?end?>

 

I would like to do something like that for the monitor as well, however the name is interface value specific, in the below case I want just Vlan, not Vlan{1} specific.

<Vlan>
  <name>{./name}</name>
  <ip>
  <flow tags="merge">

    <?if {not(/config-support[device-name=$DEVICE_NAME]/keypath[name="ios:interface/Vlan{1}/ipv6/flow/monitor\{input\}/name"]/support = 'false')}?>
      <monitor>
        <name>{$PREPEND_FLOW_NAME}-IPV4-MONITOR-IN</name>
        <direction>input</direction>
      </monitor>
    <?end?>

I am not entirely sure what it is you are after, but you can use local-name() to evaluate the name of a node if that is what you want to select on, for instance you can do xpath eval devices/device[name='ios0']/config/ios:interface/Loopback/*[local-name()='ntp'] to find all nodes under loopback named ntp, or xpath eval devices/device[name='ios0']/config//*[starts-with(.,'n')] to find all nodes under config that starts with n. Unfortunately this starts moving out of the realm I am comfortable in (and probably the area where NSO is well tested).

A simple trick, if you want to check multiple nodes that you know in advance is to use | to concatenate the sets (xpath eval /devices/device[name='ios0']/config/ios:vlan\ \|\ /devices/device[name='ios0']/config/ios:process-max-time) which works pretty well in simple cases.

Okay, I don't think I knew about some of the xpath functions that existed. After seeing the starts-with, it looks like I can use that and a contains to accomplish what I'm after. Wish it was a little more direct, but this will work.

admin@nso(config)# xpath eval /config-support[device-name='device1']/keypath[starts-with(.,'ios:interface/Vlan')][contains(.,'/ipv6/flow/monitor{input}/name']
/config-support[device-name='device1']/keypath[name='ios:interface/Vlan{1}/ipv6/flow/monitor{input}/name']
/config-support[device-name='device1']/keypath[name='ios:interface/Vlan{1}/ipv6/flow/monitor{output}/name']

I am glad – I do think that XPath is sometimes a little bit too tedious though which is why I tend to do more in python than in template. Also, I am a little bit afraid to ask what /config-support is.

config-support is a CDB modification we've made to the CDB for being able to store if configuration is supported on the device. The cisco-ios NED does not have the intelligence to determine if a device supports a command or not, so if I push a command to the device that it doesn't support in of our services, it will fail the deployment, and we'd have to modify the service or just not deploy it. This is for enterprise deployments of things like NTP, NetFlow, etc.

 

Some examples, ntp update-calendar is hardware reliant, some devices and other don't. The NED has no intelligence to determine this. We started with hard coding the models that don't support. Now with NetFlow, it's not just model, but also OS, and even license. Once again, no intelligence from the NED to deal with this, so we built a tool to automate checking if it's supported and storing it in the CDB (config-support), then we just do an xpath lookup in the XML template and if the entry exists with a support='false', we don't deploy that command. 

 

This is an enterprise issue for a large brown field of Cisco devices. For example, inside of flexible NetFlow, it was 50% of the devices that supported flexible NetFlow supported certain collect commands. So we want to push what we can to the devices as we can. Pretty cool tool, but got stuck on these XPath lookups.


Thanks for you help.