0

I'm reading data structures from YAML using Groovy, and want to convert all numbers in a map or list into strings.

Consider the following data in YAML:

young man:
  gender: male
  age: 18
  weight: 70
  height: 180
  currentHealth: 3
  smoker: no
  lackOfMobility: no
young woman:
  gender: female
  age: 19
  weight: 65
  height: 170
  currentHealth: 3
  smoker: no
  lackOfMobility: no

SnakeYAML converts this into a multi-level Map (dict, hash), with young man and young womanthe two top-level keys in the map. Values like age and height are stored as integers, which is usually ideal.

But further downstream, in my present project, age and height need to be strings in order to keep a pre-existing microservice happy.

I'd like to convert all numericals like age, weight and height to strings. And I need multi-level maps and lists to be handled correctly.

I don't want to put quotes around the numbers, which would be one way to force YAML to represent them as strings.

Someone might have solved this problem already. Are there any robust library methods that take care of stringifying numbers in an object?

2 Answers 2

2

You can configure snakeyaml to treat ints as strings by changing the constructor used.

import org.yaml.snakeyaml.Yaml
import org.yaml.snakeyaml.constructor.Constructor
import org.yaml.snakeyaml.nodes.Tag;

def input = '''
young man:
  gender: male
  age: 18
  weight: 70
  height: 180
  currentHealth: 3
  smoker: no
  lackOfMobility: no
young woman:
  gender: female
  age: 19
  weight: 65
  height: 170
  currentHealth: 3
  smoker: no
  lackOfMobility: no
'''

Constructor c = new Constructor()
c.yamlConstructors[Tag.INT] = c.yamlConstructors[Tag.STR]

Yaml yaml = new Yaml(c)
def d = yaml.load(input)

assert d."young man".age.getClass() == String
Sign up to request clarification or add additional context in comments.

Comments

0

This has worked well for for recursive List and Map types output by SnakeYAML:

static stringify(object) {
    def type = object.getClass().name
    if (type.endsWith('Map')) {
        def stringMap = new LinkedHashMap()
        object.each { k, v ->
            stringMap[k] = stringify(v)
        }
        return stringMap
    } else if (type.endsWith('List')) {
        def stringList = []
        object.each { v ->
            stringList.add(stringify(v))
        }
        return stringList
    } else {
        return object.toString()
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.