The XML parser is used to parse an XML output from a REMOTE operation.
...
For a full list of operators, see this.
XPath Power
Info |
---|
The XML Parser uses XPath v1.0, per this Crowd post: https://goo.gl/69fima |
XPath is a known path language for XML, allowing you to select specific elements. There are all kinds of cool things you can do with it, and use them in the XML parser too. For example, consider predicates (see http://www.tizag.com/xmlTutorial/xpathpredicate.php). One could _count how many elements match a certain criteria by writing this in the ind script:
Code Block |
---|
_metrics: - _groups: ${root}/TABLE_interface/ROW_interface: _temp: state: _text: "state" admin_state_down_count: _count: "admin_state[text() = 'down']" _tags: "im.name": _constant: "network-interface-admin-state" "name": _text: "interface" _transform: _value.double: | { if ("${temp.state}" == "up") { print "1.0" } else { # Slightly backwards logic, but admin_state does not appear if it is # set to up (so we can't simply try and grab its value). # So we count how many 'down' exist. if ("${temp.admin_state_down_count}" == "1") {print "0.0"} else {print "1.0"} } } |
Accessing XPath Ancestors
Sometimes a piece of data is embedded in a lower level (ancestor) but is required to complete the metric information.
...
Code Block | ||||
---|---|---|---|---|
| ||||
For the following XML data section, we would like to get the interface name from within the Lane table/row: <TABLE_interface> <ROW_interface> <interface>Ethernet1/1</interface> <sfp>present</sfp> <type>10Gbase-SR</type> <name>CISCO-JDSU </name> <partnum>PLRXPL-SC-S43-CS</partnum> <rev>1 </rev> <serialnum>JUR2003G2ZJ </serialnum> <nom_bitrate>10300</nom_bitrate> <len_50>82</len_50> <len_625>26</len_625> <len_50_OM3>300</len_50_OM3> <ciscoid>3</ciscoid> <ciscoid_1>4</ciscoid_1> <TABLE_lane> <ROW_lane> <...> <tx_pwr>-2.24</tx_pwr> <tx_pwr_flag> </tx_pwr_flag> <tx_pwr_alrm_hi>1.69</tx_pwr_alrm_hi> <tx_pwr_alrm_lo>-11.30</tx_pwr_alrm_lo> <tx_pwr_warn_hi>-1.30</tx_pwr_warn_hi> <tx_pwr_warn_lo>-7.30</tx_pwr_warn_lo> <...> </ROW_lane> </TABLE_lane> </ROW_interface> - _groups: # Tx Power Alarm: 0.0 if Tx Power is within warning range ${root}/TABLE_interface/ROW_interface/TABLE_lane/ROW_lane[not(lane_number)]: _temp: tx_pwr: _text: "tx_pwr" low: _text: "tx_pwr_warn_lo" high: _text: "tx_pwr_warn_hi" interface: _text: ancestor::node()/interface _tags: "im.name": _constant: "hardware-element-status" "live-config": _constant: "true" "display-name": _constant: "Optics" "im.dstype.displayType": _constant: "state" "im.identity-tags": _constant: "name" _transform: _value.double: | { if ((${temp.tx_pwr} < ${temp.low}) || (${temp.tx_pwr} > ${temp.high})) { print "0.0" } else { print "1.0" } } _tags: "name": | { print "Optic Tx Power State ${temp.interface}" } "interface": | { print "${temp.interface}" } |
Important Note: Missing paths
If a certain path doesn't exist, the parser will skip that metric (because it will consider the path as a failure). For example, consider this:
...
Code Block |
---|
_metrics: - _temp: subelementcount: _count: somepath/somesubelement _transform: _value.double: | { if ("${temp.subelementcount}" == "0") { print "0" } else { print "1" } } |
Testing an XPATH against your input
There are a few XPATH testers out there that you can use to test an XPATH against an input file. One of the better ones are codebeautify.org.
http://codebeautify.org/Xpath-Tester
Removing name space
Before testing, make sure to remove all xmlns attributes from your input file as this would give you head aches.
Example
Original input:
Code Block |
---|
<rpc-reply xmlns:junos="http://xml.juniper.net/junos/12.1X46/junos"> <interface-information xmlns="http://xml.juniper.net/junos/12.1X46/junos-interface" junos:style="normal"> |
...
Code Block |
---|
<rpc-reply> <interface-information junos:style="normal"> |
Good practices
It is recommended to put the sections in this order if possible:
...