人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

phpの質問です。
以下のデータがあるとして
<rank point="9000" order="1" index="1">
<team area3="青葉区" area2="横浜市" area1="神奈川県" email="" url="" name="AAAAA" id="00001"/> </rank>
<rank point="8000" order="2" index="2">
<team area3="青葉区" area2="横浜市" area1="神奈川県" email="" url="" name="BBBBB" id="00002"/> </rank>
<rank point="7000" order="3" index="3">
<team area3="西区" area2="横浜市" area1="神奈川県" email="" url="" name="CCCCC" id="00003"/></rank>
<rank point="6000" order="4" index="4">
<team area3="瀬谷区" area2="横浜市" area1="神奈川県" email="" url="" name="DDDDD" id="00004"/> </rank>
<rank point="5000" order="5" index="5">
<team area3="西区" area2="横浜市" area1="神奈川県" email="" url="" name="EEEEE" id="00005"/> </rank>


出力結果を
神奈川県(5)
└─横浜市(5)
└─西区(2)
└─青葉区(2)
└─瀬谷区(1)
と、yahooUIのツリー表示を使って(使わなくてもいいんですが)
件数を表示できるようなやり方を教えてください。

関連した過去の質問です
http://q.hatena.ne.jp/1311135822
よろしくお願いします

●質問者: vfr6822
●カテゴリ:就職・転職 ウェブ制作
○ 状態 :終了
└ 回答数 : 2/2件

▽最新の回答へ

1 ● tdoi
●50ポイント

こんな感じでいかがでしょう?

前回の質問と同じようにパースして、再帰的に処理をしているだけです。

ツリー状にするのは、とりあえずインデントで明示するようにしましたが、これでいいでしょうか?

もっと効率のよいコードも書けると思いますが、目的が分からないのでこのくらいで。

<?php
$result = parseXml('sample.xml');
outputResult($result);

function parseXml($filename)
{
 $xml = file_get_contents($filename);
 $document = new SimpleXMLElement($xml);

 $result = array();
 foreach ($document->rank as $rank) {
 $area1 = strval($rank->team['area1']);
 $area2 = strval($rank->team['area2']);
 $area3 = strval($rank->team['area3']);
 if (!isset($result[$area1])) {
 $result[$area1] = array();
 }
 if (!isset($result[$area1][$area2])) {
 $result[$area1][$area2] = array();
 }
 if (!isset($result[$area1][$area2][$area3])) {
 $result[$area1][$area2][$area3] = 0;
 }
 ++$result[$area1][$area2][$area3];
 }

 return $result;
}

function outputResult($result, $offset = '')
{
 foreach ($result as $key => $node) {
 echo $offset . $key . "(" . getCount($node) . ")\r\n";
 if (is_array($node)) {
 outputResult($node, $offset . "----");
 }
 }
}

function getCount($node)
{
 if (is_array($node)) {
 $count = 0;
 foreach ($node as $child) {
 $count += getCount($child);
 }
 } else {
 $count = $node;
 }

 return $count;
}
?>

こんな出力になります。

神奈川県(5)
----横浜市(5)
--------青葉区(2)
--------西区(2)
--------瀬谷区(1)

何かの参考になれば。

◎質問者からの返答

うまく出力結果が表示できませんでしたがありがとうございました!


2 ● tobeoscontinue
●100ポイント ベストアンサー

またしても前回の応用です。

データーはxmlとしたのでrankの外を何かで囲む必要があります。

肝は$area["$a1"]["$a2"]["$a3"][]の部分です。連想配列を使うことで同じものは勝ってに集まるのでただループして追加していくだけです。


array((string)$rank["point"], (string)$rank["order"],(string)$rank->team["id"], (string)$rank->team["name"],(string)$rank->team["url"], (string)$rank->team["email"]);

の部分は応用として使うことがあるかなぁということで今は使用してません。


連想配列で階層は表現できているのですが件数は拾はないといけないのでソースが汚いです。

本来は県->市->区の順に処理できればいいのですが区を処理して件数を求めてから市を処理し、更に県を処理するということをしています。

後はhtmlにscriptを埋め込んで終了です。


phpのコードとjavascriptのコードが混在して可読性が悪いです。

javascriptでsample.xmlのようなデータを落としてツリーを構築するやりかたの方がいいのではないでしょうか。

<?php
function tree_view_xml($name, $xml, $CR="\n") {
$xml = simplexml_load_file($xml);

$area = array();
foreach($xml->rank as $rank) {
$a1 = $rank->team["area1"];
$a2 = $rank->team["area2"];
$a3 = $rank->team["area3"];
$area["$a1"]["$a2"]["$a3"][] = array((string)$rank["point"], (string)$rank["order"],
(string)$rank->team["id"], (string)$rank->team["name"],
(string)$rank->team["url"], (string)$rank->team["email"]);
}
$yui_tree ='var tree;
window.onload = function(){
tree = new YAHOO.widget.TreeView("treeData");
var root = tree.getRoot();'.$CR;
foreach($area as $pref=>$a2) {
$a2_tree = '';
$a2_count = 0;
foreach($a2 as $city=>$a3) {
$a3_tree = '';
$a3_count = 0;
foreach($a3 as $dist=>$m) {
$a3_count += count($m);
 $a3_tree .= 'new YAHOO.widget.TextNode("'.$dist.'('.count($m).')", city, false);'.$CR;
}
$a2_count += $a3_count;
 $a2_tree .= "var city = new YAHOO.widget.TextNode(\"${city}(${a3_count})\", pref, false);".$CR.$a3_tree;
}
 $yui_tree .= "var pref = new YAHOO.widget.TextNode(\"${pref}(${a2_count})\", root, false);".$CR.$a2_tree;
}
return $yui_tree.'tree.draw();'.$CR.'}'.$CR;
}
?>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>vfr6822:1319087945</title>
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.8.1/build/treeview/assets/skins/sam/treeview.css">
<script type="text/javascript" src="http://yui.yahooapis.com/2.8.1/build/yahoo-dom-event/yahoo-dom-event.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.8.1/build/treeview/treeview-min.js"></script>
<script type="text/javascript"><!--
<?php echo tree_view_xml("treeData", "./sample.xml") ?>
// --></script>
</head>
<body>
<h1>vfr6822:1319087945</h1>
<form>
<input type="button" value="全て展開" onClick="tree.expandAll()">
<input type="button" value="全て折り畳む" onClick="tree.collapseAll()">
</form><div id="treeData"></div>
</body>
</html>
関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ