In the XML parser, we have several operators which need to be used at different levels.

Top-level operators:

Value-level operators:

Metrics can be either DOUBLE (a number) or COMPLEX (essentially a JSON structure):

When grabbing a value (for the double metric, for a temporary variable (discussed further below) or for a value in a JSON structure), you can use these operators: 

In order to iterate over multiple elements which match a certain xpath (for example, a list of users, or a list of disks), use the _groups section. For example:

_metrics:
    -
        _groups:
            ${root}/job:                    # This will iterate over each element called "job".
                _value.complex:
                    id:
                        _text: "id"
                    status:
                        _text: "status"
                    result:
                        _text: "result"
                    details:
                        _text: "details"
                _tags:
                    "im.name":
                        _constant: "jobs"
          _value: complex-array			   # Tells the parser to treat this as a JSON array - multiple objects, each has the id, status, result and details keys

Lastly, there's the _transform block. This allows you to translate the contents you've pulled from the XML to the format the metrics need. You use _awk to do this. For example:

_metrics:
    -
        _tags:
            "im.name":
                _constant: "uptime-seconds"
            "live-config":
               _constant: "true"
            "display-name":
                _constant: "Uptime"
            "im.dstype.displayType":
                _constant: "seconds"
        _temp:
            "uptime":
                _text: "/response/result/system/uptime"
        _transform:
            _value.double: | 
               {
                   # 230 days, 16:57:34
                split("${temp.uptime}", vals, " ")
                if (arraylen(vals) == 3  && vals[2] == "days,") {
                    # 230 days, 16:57:34
                    days = vals[1]
                    split(vals[3], timevals, ":")
                    hours = timevals[1]
                    minutes = timevals[2]
                    seconds = timevals[3]
                    uptime = (days * 3600 * 24) + (hours * 3600) + (minutes * 60) + seconds
                    print uptime
                }
               }


_metrics:
    -
        _groups:
            ${root}/*:
                _temp:
                    status: 
                        _text: "status"
                _tags:
                    name:
                        _text: "name"
                    "im.name":
                        _constant: "ntp-server-state"
                    "live-config":
                       _constant: "true"
                    "display-name":
                        _constant: "NTP Servers - State"
                    "im.dstype.displayType":
                        _constant: "state"
                    "im.identity-tags":
                        _constant: "name"
        _transform:
            _value.double: |
                {
                    if ("${temp.status}" == "synched") {print "1.0"} else {print "0.0"}
                }

If you want to try and grab information from a parent element, use ancestor, like here:

_metrics:
    -
        _groups:
            ${root}/data-processors/*/second/cpu-load-average/entry:
                _value.double:
                    _text: value
                _temp:
                    coreid:
                        _text: "coreid"
                    dpid:
                        _name: ancestor::node()[3]
                _tags:
                    "im.name":
                        _constant: "cpu-usage"
                    "live-config":
                       _constant: "true"
                    "display-name":
                        _constant: "CPU Usage"
                    "im.dstype.displayType":
                        _constant: "percentage"
                    "im.identity-tags":
                        _constant: "cpu-id"
                    "cpu-is-avg":
                        _constant: "false"
        _transform:
            _tags:
                "cpu-id": |
                    {
                        print "${temp.dpid}: ${temp.coreid}"
                    }