Yahoo!みんなの検定ProjectのK.K.です。
前回、【「三国志」に関する検定を表示し、受験する】という
機能を作成するため、検定リストAPIを使うということを説明しました。
今回は、「検定詳細API」を使って、問題を表示してみましょう。
ひとまず、表示する内容を
・「三国志」のキーワードを持つ
・作成された最新の検定から
・ランダムで1問表示する
に絞ってみましょう。
では、PHPでのサンプルを使って説明していきます。
APIのレスポンスとして返ってくるXML。
これのパース方法は、PHP5では「SimpleXML関数」が強力なのですが、
PHP4でも動くPEARの「XML_Unserializer」ライブラリを使用しています。
これで「三国志」のキーワードを持つ最新の検定の情報を取得し、
検定に個別に割り振られている「検定ID」を抽出することができるようになりました。
ランダムに1問だけ表示したいですが、検定によって問題数が5問〜8問までさまざまです。
問題数を示す「QuestionCount」を抽出して、その中から何問目かをランダムで取得するようにしましょう。
検定IDと、何問目を取得するかを抽出できたので、
これをもとに検定詳細APIを呼び出し、パースします。
このようにして、問題表示に必要そうな情報を取得することができました。
これを使っていろいろなことができそうですが、
とりあえずシンプルに表示だけしてみます。
準備完了。htmlとして表示します。
今回は1問だけランダムで取得してきましたが、全問取得したり、
複数の検定からまたいで問題を取得したりと応用できますので、
あっと驚くような使い方を期待してます。
なお、検定には「何問中何問以上で合格」といった基準や
正解数に応じて評価メッセージが設定されているものもあります。
検定の解答結果から、その評価を返す「検定受験API」も、
また紹介していこうと思います。
受けて作ってつながろう!
Yahoo!みんなの検定
前回、【「三国志」に関する検定を表示し、受験する】という
機能を作成するため、検定リストAPIを使うということを説明しました。
今回は、「検定詳細API」を使って、問題を表示してみましょう。
ひとまず、表示する内容を
・「三国志」のキーワードを持つ
・作成された最新の検定から
・ランダムで1問表示する
に絞ってみましょう。
では、PHPでのサンプルを使って説明していきます。
APIのレスポンスとして返ってくるXML。
これのパース方法は、PHP5では「SimpleXML関数」が強力なのですが、
PHP4でも動くPEARの「XML_Unserializer」ライブラリを使用しています。
<?php
require_once 'XML/Unserializer.php';
// みんなの検定APIの基本URL
$API_BASE_URL = 'http://cert.yahooapis.jp/MinnaCertWebService/V1/';
// APP_ID
$APP_ID = '{あなたのAPP_ID}';
// 指定するキーワード
$KEYWORD = '三国志';
// 検定一覧APIのURL(order=1:公開日の降順 amount=1:1件取得)
$LIST_API_URL = $API_BASE_URL . 'certList?' . http_build_query(
'appid' => $APP_ID,
'order' => 1,
'amount' => 1,
'keyword' => $KEYWORD
);
// 検定詳細APIのURL(get_q=2:問題情報+正解と解説を取得)
$DETAIL_API_URL = $API_BASE_URL . 'certDetail?' . http_build_query(
'appid' => $APP_ID,
'get_q' => 2
'cert_id' => null
);
/*
*
* XMLのパース
*
*/
// XMLパース用クラス作成
$class_xml_uns = new XML_Unserializer(array('parseAttributes' => true));
// 検定一覧XMLのパース実行
$class_xml_uns->unserialize(file_get_contents($LIST_API_URL));
// パース結果を配列に格納
$res_list = $class_xml_uns->getUnserializedData();
これで「三国志」のキーワードを持つ最新の検定の情報を取得し、
検定に個別に割り振られている「検定ID」を抽出することができるようになりました。
/*
* 検定の各情報を抽出
*/
// 検定の詳細を取得
$ary_cert = $res_list['Result'];
// 検定ID抽出
$cert_id = $ary_cert['CertId'];
// 検定名抽出
$cert_name = mb_convert_encoding($ary_cert['CertName'], 'EUC-JP', 'UTF-8');
// 検定のURLを抽出
$cert_url = $ary_cert['CertDetailPcUrl'];
ランダムに1問だけ表示したいですが、検定によって問題数が5問〜8問までさまざまです。
問題数を示す「QuestionCount」を抽出して、その中から何問目かをランダムで取得するようにしましょう。
// 検定の中からランダムに1問取得する
$order_number = mt_rand(1, $ary_cert['QuestionCount']);
検定IDと、何問目を取得するかを抽出できたので、
これをもとに検定詳細APIを呼び出し、パースします。
// 抽出したIDで指定した検定の詳細XMLのパース実行
$class_xml_uns->unserialize(file_get_contents($DETAIL_API_URL . $cert_id . "&order_number=" . $order_number));
// パース結果を配列に格納
$res_detail = $class_xml_uns->getUnserializedData();
$ary_detail = $res_detail['Result']['QuestionResult']['QuestionData'];
// 問題文抽出
$question_text = mb_convert_encoding($ary_detail['QuestionText'], 'EUCJP-WIN', 'UTF-8');
$question_text = str_replace("\n" ,"<br>", $question_text);
// 選択肢抽出
$choice = '';
foreach ($ary_detail['ChoicesResult']['ChoiceData'] as $ary_choice ) {
$choice_number = $ary_choice['OrderNumber'];
$choice_text = mb_convert_encoding($ary_choice['ChoiceText'], 'EUCJP-WIN', 'UTF-8');
$choice .= '(' . $choice_number . ')' . $choice_text . '<br>';
}
// 正解抽出
$answer = $ary_detail['CorrectAnswer'];
// 解説抽出
$explanation = mb_convert_encoding($ary_detail['QuestionExplanation'], 'EUCJP-WIN', 'UTF-8');
if ( $explanation == '' ) {
$explanation = '※解説はありません';// 解説は必須ではないので空の場合あり
} else {
$explanation = str_replace("\n", '<br>', $explanation);
}
このようにして、問題表示に必要そうな情報を取得することができました。
これを使っていろいろなことができそうですが、
とりあえずシンプルに表示だけしてみます。
/**
* HTML部分作成
* とりあえず、「答えを見る」ボタンを押すと、
* 折りたたんである答えが表示されるだけのシンプルなもの。
*/
// 問題部分のHTMLを作成
$question_html = <<<_HTML_
${cert_name}<br>
<br>
${question_text}<br>
<br>
[ 選択肢 ]<br>
${choice}
_HTML_;
// 解答部分のHTMLを作成
$answer_html = '[ 正解 ] (' . $answer . ')<br>[ 解説 ]' . $explanation .
'<br><a href="' . $cert_url . '" target="_brank">ほかの問題も解いてみる</a>';
準備完了。htmlとして表示します。
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>サンプル</title>
</head>
<body>
<?php echo $question_html ?>
<form>
<input type="button" id="answer" value="答えを見る" onClick="answerOn();">
<script type="text/javascript">
function answerOn() {
var answer = '<?php echo $answer_html ?>';
document.getElementById("result").innerHTML = answer;
}
</script>
</form>
<div id="result"></div>
</body>
</html>
今回は1問だけランダムで取得してきましたが、全問取得したり、
複数の検定からまたいで問題を取得したりと応用できますので、
あっと驚くような使い方を期待してます。
なお、検定には「何問中何問以上で合格」といった基準や
正解数に応じて評価メッセージが設定されているものもあります。
検定の解答結果から、その評価を返す「検定受験API」も、
また紹介していこうと思います。
受けて作ってつながろう!
Yahoo!みんなの検定
こちらの記事のご感想を聞かせください。
- 学びがある
- わかりやすい
- 新しい視点
ご感想ありがとうございました