I am trying to improve the way I get values out of YAML data in Jenkins Groovy.
Example YAML:
---
customers:
- customernumber: 477563
first_name: Dorothy
family_name: Gale
order:
- ordernumber : 876234786
orderdate : 202501231456
items:
- part_no: A4786
description: Water Bucket Filled
price: 1.47
quantity: 4
- part_no: E1628
description: High Heeled Ruby Slippers
size: 8
price: 133.7
quantity: 1
- customernumber: 6782545
first_name: Fairy
family_name: Godmother
order:
- ordernumber : 876234790
orderdate : 202501271223
items:
- part_no: A5736
description: Magic Wand
price: 8.23
quantity: 1
- part_no: E7456
description: Glitter 1Kg
price: 13.99
quantity: 1
- part_no: A3524
description: Axe
price: 10.99
quantity: 1
Example code to get a quantity value given a customer number, an order number, and a part number, ie a unique path into the YAML data :
String getQuantity(yamldata, customernumber, ordernumber, partnumber) {
for (customernumber_item in yamldata.customers) {
if (customernumber_item.customernumber == customernumber) {
for (order_item in customernumber_item.order) {
if (order_item.ordernumber == ordernumber) {
for (item_item in order_item.items) {
if (item_item.part_no == partnumber) {
return item_item.quantity
}
}
}
}
}
}
// Default if the item wasn't found
return null
}
<...>
YAMLDATA = readYaml(file: 'example.yaml')
quantity = getQuantity(YAMLDATA,'477563','876234786','E1628')
As you can see, I have a working function, but it is clumsy and very inefficient. There must be a more elegant, Groovy way?
Things I have tried:
GPaths, things like : quantity = YAMLDATA.customers*.customernumber['477563']...
. I think I got close to a solution with GPaths, but this only seems to work if the leaf I'm looking for is at the end of the path. In this case it is not, it is in an adjacent path.
findAll. As far as I can see this won't work as there are potential duplicates of key value pairs in the YAML, and I really need the value at a specific leaf in a path in the YAML tree.
Thanks in advance.
So you could do this:
println( yaml.customers.find { it.customernumber == 477563 }
?.order.find { it.ordernumber == 876234786 }
?.items.find { it.part_no == 'A4786' }
?.quantity )
One thing I noticed is that customernumber
and ordernumber
are integers because they aren't surrounded by quotes in the YAML file and consist of all numbers. Once I figured that out the above expression worked.