def validate_data(rootname, source, schema)
      return nil if source.nil?

      good_data = {}
      source.each do |key, value|
        ksym = key.to_sym
        expected_type = schema[ksym].class == Class ? schema[ksym] : Hash
        if !schema.include?(ksym)
          puts "Warning: unknown field '#{ksym}' under definition for #{rootname}"
        elsif value.nil?
          good_data[ksym] = nil
        elsif value.class != expected_type
          puts "Warning: expected field '#{ksym}' of #{rootname} to be '#{expected_type}', got '#{value.class}'"
        else
          good_data[ksym] = value.class == Hash ? validate_data(key, value, schema[ksym]) : value
        end
      end
      good_data
    end
def validate_data(rootname, source, schema)
      return nil if source.nil?

      good_data = {}
      source.each do |key, value|
        ksym = key.to_sym
        expected_type = schema[ksym].class == Class ? schema[ksym] : Hash
        if !schema.include?(ksym)
          puts "Warning: unknown field '#{ksym}' under definition for #{rootname}"
        elsif value.nil?
          good_data[ksym] = nil
        elsif value.class != expected_type
          puts "Warning: expected field '#{ksym}' of #{rootname} to be '#{expected_type}', got '#{value.class}'"
        else
          good_data[ksym] = value.class == Hash ? validate_data(key, value, schema[ksym]) : value
        end
      end
      good_data
    end
validate a data source according to a schema
 print out warnings for bad fields, and return only the good ones
 @param rootname [String] the name, for printing
 @param source [Hash] source data
 @param schema [Hash] a mapping of field names to their expected type
 @return [Hash] a copy, containing only expected & valid data