Search code examples
stringgroovycastingnumberssnakeyaml

Java/Groovy method for stringifying numbers in an object?


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?


Solution

  • 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