火曜日, 6月 23, 2015

コマンドラインでシカゴの気温を調べる(C# で JSON データを読む)

先日 Java での JSON データの読み方を紹介しました。

ここでは C# で JSON データを読む方法を紹介します。

DataContractJsonSerializer を使った方法です。

DataContractJsonSerializer.ReadObject() を使うと JSON データを読み、オブジェクトとして出力してくれます。

オブジェクトへの変換が「宣言」となっているところがいくらか分かりやすいといえるでしょうか。

まず、読み込みたいデータ構造をクラスとして宣言し、DataContract 属性を付加します。JSON データは DataMember 属性を付加します。ネストされているデータはクラスとして宣言しDataContract 属性を付加します。コードを参照してください。#配列データは配列として宣言します。

出来上がったデータクラスを DataContractJsonSerializer のコンストラクタの引数として渡します。

準備が出来たらHttpWebResponse として読んできたデータを、DataContractJsonSerializer.ReadObject() で読み込みます。

と、この手順を踏むとめでたく JSON データが読み込めます。あとは出力するだけ。

ここの気温の表示はデフォルト設定でなんとK(ケルビン)です。ので 273.15 を引いてやります。

#華氏(℉)か摂氏(℃)か迷ったんでしょうか(もめたんですかね)。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Threading.Tasks;
using System.Net;
namespace JSONTest
{
class Program
{
static void Main(string[] args)
{
try
{
String url = "http://api.openweathermap.org/data/2.5/weather?q=chicago";
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
if (response.StatusCode != HttpStatusCode.OK)
throw new Exception(String.Format(
"Server error (HTTP {0}: {1}).",
response.StatusCode,
response.StatusDescription));
DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(Response));
object objResponse = jsonSerializer.ReadObject(response.GetResponseStream());
Response jsonResponse = objResponse as Response;
//Console.WriteLine(jsonResponse.main.temp - 273.15);
jsonSerializer.WriteObject(Console.OpenStandardOutput(), jsonResponse);
Console.ReadLine();
}
}
catch (Exception e)
{
Console.Error.WriteLine(e.ToString());
//throw e;
Console.ReadLine();
}
}
}
[DataContract]
public class Response
{
[DataMember(Name = "main")]
public Main main { get; set; }
[DataMember(Name = "coord")]
public Coord coord { get; set; }
[DataMember(Name = "sys")]
public Sys sys { get; set; }
[DataMember(Name = "weather")]
public Weather[] weather { get; set; }
[DataMember(Name = "wind")]
public Wind wind { get; set; }
[DataContract]
public class Coord
{
[DataMember(Name = "lon")]
public double lon { get; set; }
[DataMember(Name = "lat")]
public double lat { get; set; }
}
[DataContract]
public class Sys
{
[DataMember(Name = "message")]
public double message { get; set; }
[DataMember(Name = "country")]
public string country { get; set; }
[DataMember(Name = "sunrise")]
public long sunrise { get; set; }
[DataMember(Name = "sunset")]
public long sunset { get; set; }
}
[DataContract]
public class Weather
{
[DataMember(Name = "id")]
public long id { get; set; }
[DataMember(Name = "main")]
public string main { get; set; }
[DataMember(Name = "description")]
public string description { get; set; }
[DataMember(Name = "icon")]
public string icon { get; set; }
}
[DataMember(Name = "base")]
public string _base { get; set; }
[DataContract]
public class Main
{
[DataMember(Name = "temp")]
public double temp { get; set; }
[DataMember(Name = "temp_min")]
public double temp_min { get; set; }
[DataMember(Name = "temp_max")]
public double temp_max { get; set; }
[DataMember(Name = "pressure")]
public double pressure { get; set; }
[DataMember(Name = "sea_level")]
public double sea_level { get; set; }
[DataMember(Name = "grnd_level")]
public double grnd_level { get; set; }
[DataMember(Name = "humidity")]
public long humidity { get; set; }
}
[DataContract]
public class Wind
{
[DataMember(Name = "speed")]
public double speed { get; set; }
[DataMember(Name = "deg")]
public double deg { get; set; }
}
[DataContract]
public class Clouds
{
[DataMember(Name = "all")]
public long all { get; set; }
}
[DataMember(Name = "dt")]
public long dt { get; set; }
[DataMember(Name = "id")]
public long id { get; set; }
[DataMember(Name = "name")]
public string name { get; set; }
[DataMember(Name = "cod")]
public long cod { get; set; }
}
}

木曜日, 6月 11, 2015

コマンドラインでシカゴの気温を調べる(Java で JSON データを読む)

なんと、近々発表されるはずの Java 9 から JSON ライブラリが外されてしまいました。

これは、政治ですね?(笑・XML派の妨害ですね。)

JSON ってコンパクトですよね。名前なしの{}(中括弧)を使うところが XML 形式より多少なりとも不確実ではあっても記述が短くて済むわけです。

openweathermap サイトのデフォルト設定は JSON 出力です。

{"coord":{"lon":-87.65,"lat":41.85},"sys":{"message":1.2238,"country":"US","sunrise":1434017699,"sunset":1434072341},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"}],"base":"stations","main":{"temp":290.857,"temp_min":290.857,"temp_max":290.857,"pressure":1002.52,"sea_level":1024.25,"grnd_level":1002.52,"humidity":74},"wind":{"speed":2.13,"deg":53.5001},"clouds":{"all":48},"rain":{"3h":0.595},"dt":1434048065,"id":4887398,"name":"Chicago","cod":200}
view raw Chicago Weather hosted with ❤ by GitHub


このサイトは天気情報を提供してくれます。都市名とかを URL で送ってやると天気情報を返してくれます。

そこで、「ねえ、パーサーを書いたら?」とかいう余計な手間をかけたくない忙しいプログラマのため org.json.simple ライブラリの使い方を紹介します。

まず JSON.simple JAR ファイルをダウンロード


データを読み込むプログラムの手順を示します。

  1. まず、JSONParser オブジェクトをインスタンス化。
  2. URL オブジェクトから InputStreamReader、BufferedReader をインスタンス化。
  3. JSONParser.parse() でパース。
  4. あとは JSONParser.get() で要素を読んでいくだけです。
  5. ネストされている要素であれば、JSONParser オブジェクトとして扱う。

// WeatherApp.java -- Get Chicago weather from openweathermap site
// Copyright (c) 2015 easai
// Author: easai
// Created: Thu Jun 11 13:23:04 2015
// Keywords:
// This file is not part of GNU Emacs.
// WeatherApp.java is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or (at your option)
// any later version.
// This software is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; see the file COPYING. If not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
// Commentary:
//
//
//
// Code:
import java.io.*;
import java.net.*;
import java.util.*;
import org.json.simple.*;
import org.json.simple.parser.*;
public class WeatherApp
{
public static void main(String args[])
{
JSONParser parser=new JSONParser();
try
{
URL url = new URL("http://api.openweathermap.org/data/2.5/weather?q=chicago");
try (BufferedReader reader
= new BufferedReader(new InputStreamReader(url.openStream())))
{
JSONObject obj = (JSONObject)parser.parse(reader);
JSONObject main = (JSONObject)obj.get("main");
double temp = (double)main.get("temp")-273.15;
System.out.println(temp);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
// WeatherApp.java ends here
view raw WeatherApp.java hosted with ❤ by GitHub

あとは、JAR ファイルとコンパイルするだけ。

javac -classpath "JARファイルのあるディレクトリ;." WeatherApp.java
これで、コマンドラインからシカゴの気温が検索できます。

Qt: 外部プログラムを起動する

  Qt/C++ のアプリは、外部へ直接アクセスできます。これはネットアプリでは不可能な Qt のメリットです。 外部プログラムを起動することもできます。QProcess::startDetached() を使うと独立したプロセスを立ち上げることができます。 この QProces...