google taxonomy Liste zu Array mit Parent_Id
lima-city → Forum → Programmiersprachen → PHP, MySQL & .htaccess
array
aufruf
baum
code
display
ebene ende
ebene start
ebenen code
element
ende
erstellen
farbe
funktion
http
kategorie
level
listen
start
struktur
url
-
Hallo
wie bekomme ich aus dieser txt-Datei
http://www.google.com/basepages/producttype/taxonomy.de-DE.txt
ein Array mit je Element mit ID, Name und ParentID
also so
array ( [0] => array( ['ID'] => 0 ['Name'] => Root ['ParentID'] => x ) [1] => array( ['ID'] => 1 ['Name'] => Baby & Kleinkind ['ParentID'] => 0 ) [2] => array( ['ID'] => 2 ['Name'] => Baby baden ['ParentID'] => 1 ) [3] => array( ['ID'] => 3 ['Name'] => Babybadewannen ['ParentID'] => 2 ) [4] => array( ['ID'] => 4 ['Name'] => Babygesundheit ['ParentID'] => 1 ) [5] => array( ['ID'] => 5 ['Name'] => Nasensauger ['ParentID'] => 4 ) [6] => array( ['ID'] => 6 ['Name'] => Schnuller & Beißringe ['ParentID'] => 4 ) ... usw )
oder auch als Array mit der Struktur als Hirarchie
gibts für sowas fertige funktionen oder klassen ?
-
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
also erstmal die Liste zu Array mit id, parent_id, level und name
... das mit $max_deep kann man auch weglassen,
ist nur so zur Info wie die maxiamale Tiefe der Kategorien-Ebenen ist
EDIT: komplettes Script (in einer .php Datei) hier http://pastebin.com/7Gk0CxTr
// ----------------------------------------------------- $filename = 'taxonomy.de-DE.txt'; $fdata1 = file($filename, FILE_IGNORE_NEW_LINES); // ----------------------------------------------------- $kat_temp = array(); // --- Hilfs-Array ID->Name $kat_data = array(); // --- Ergebnis-Array Daten c = 0; // --- max. Tiefe der Kategorie-Ebenen // ----------------------------------------------------- foreach($fdata1 as $key => $line) { if ($key > 0) { // ------ Kategorie Ebene ($level) ermitteln ----- $nx = substr_count($line, '>'); if ($nx > $max_deep) { $max_deep = $nx; } $level = $nx; // ------ Element in Array $kat_temp erstellen ----- $subarray = explode('>', $line); $kat_name = trim($subarray[$nx]); $kat_temp[$key] = $kat_name; // ------ parent_id aus $kat_temp ermitteln ----- if ($nx > 0) { $ny = ($nx-1); $kat_pren = trim($subarray[$ny]); $kat_prek = array_search($kat_pren, $kat_temp); } else { $kat_pren = 'root'; $kat_prek = '0'; } // ------ Neues Array-Element erstellen ----- $kat_data[$key] = array( 'id' => $key, 'parent_id' => $kat_prek, 'level' => $level, 'name' => $kat_name ); unset($subarray); } } unset($kat_temp); // ----------------------------------------------------- echo "<br />\n"; echo "<br />Max Deep: ".$max_deep."\n"; echo "<br />\n"; ## print "<pre style=\"margin:8px; padding:6px; background:#DEDEDE;\">\n"; ## print_r($kat_data); ## print "</pre>\n"; // -----------------------------------------------------
und dann ... die id / parent_id Daten in Struktur Array mit Ebenen
// ----------------------------------------------------- $outputArray = array(); $nodeRefs = array(0 => &$outputArray); foreach ($kat_data as $element) { $parent = &$nodeRefs[$element['parent_id']]; $parent[$element['id']] = array( 'name' => $element['name'], 'parent_id' => $element['parent_id'], 'sub' => array() ); $nodeRefs[$element['id']] = &$parent[$element['id']]['sub']; } ## print "<pre style=\"margin:8px; padding:6px; background:#DEDEDE;\">\n"; ## print_r($outputArray); ## print "</pre>\n"; // -----------------------------------------------------
... dann kann man mit dem $outputArray eine Menü-Struktur (ul / li) erstellen ...
]// ----------------------------------------------------------------- function print_tree($array, $level=0, $view=1) { global $go_shopid; if ($level == 0) { print "<ul id=\"katroot\" style=\"background:#DEDEDE;\">\n"; } foreach($array as $key => $val) { $level++; if ( isset($val['sub']) && !empty($val['sub']) ) { $preid = $val['parent_id']; print "<li>".$val['name']." (<a href=\"javascript:show('".$key.$level."')\">".$preid." / ".$key."</a>) - ".$level.""; if ($level == 1) { $ulcolor = 'background:#FFFFCC;'; } elseif ($level == 2) { $ulcolor = 'background:#CCFFFF;'; } elseif ($level == 3) { $ulcolor = 'background:#FFFFFF;'; } else { $ulcolor = 'background:#FFCCFF;'; } if ($level >= $view) { $ulview = 'display:none;'; } else { $ulview = 'display:block;'; } $ulstyle = 'style="'.$ulview.' '.$ulcolor.'"'; print "\n<ul id=\"".$key.$level."\" ".$ulstyle.">\n"; print_tree($val['sub'], $level, $view); print "</li>\n</ul>\n"; } else { print "<li>".$val['name']." (".$key.") - ".$level."</li>\n"; } $level--; } if ($level == 0) { print "</ul>\n"; } } // ----------------------------------------------------------------- print "<br />\n"; print "<br />\n"; print "<br />\n"; $data_array = $outputArray; $startlevel = 0; $open_level = 2; print_tree($data_array, $startlevel, $open_level); print "<br />\n"; print "<br />\n"; print "<br />\n"; // -----------------------------------------------------------------
für das Auf-/zuklappen mit Link javascript:show() braucht man noch als javascript
<script type="text/javascript"> function show(id) { if (document.getElementById(id).style.display == "none") { document.getElementById(id).style.display = "block"; } else { document.getElementById(id).style.display = "none"; } } </script>
fertig. :)
Beitrag zuletzt geändert: 31.8.2012 14:04:53 von webguide -
Hallo
Danke, sieht ja schon gut aus,
da ist ein Fehler im Code:
c = 0; // --- max. Tiefe der Kategorie-Ebenen
Variable als Buchstabe ohne $ definiert ?!?
Wenn ich diese Zeile raus mache,dann geht's
aber die google taxonomy Kategorie-Liste hat 7 Ebenen,
mit Deinem Code bekomme ich aber nur $max_deep = 6;
man kann die 7.Ebene dann zwar doch aufklappen,
wenn man Sie im Baum findet, aber oben drüber steht Max Deep: 6
aber sonst echt schön, das mit dem auf-/zu-klappen der <ul>
Danke !!! -
c = 0; // --- max. Tiefe der Kategorie-Ebenen
soll wohl heissen;
$max_deep = 0; // --- max. Tiefe der Kategorie-Ebenen
ja und noch mehr
ein nicht sofort erkennbarer "Fehler" in der Funktion print_tree()
es wird keine saubere (valide) ul / li Struktur erzeugt,
... wenn eine Unter-Ebene zu Ende ist, kommt nur </ul>
es sollte aber </ul> und </li> kommen
.... wird zwar "normal" angezeigt im Browser, aber im Quellcode sieht man es dann
und das
macht auch keinen Sinn,global $go_shopid;
diese Variable wird in der Funktion dann nirgends verwendet, kann man also weg lassen
in der neuen Version: 2 (Code siehe weiter unten)
habe auch noch einen $spacer eingeführt, für Einrückung des erzeugten HTML-Code
anstatt "\t" (Tabs) könnte man da auch ' ' (Leerzeichen) machen (mit ## auskommentiert)
und zu den Farben der einzelnen Ebenen:
... in der Funktion ist ja bisher ein if ... elseif ... das nur für 6 Ebenen Farben ändert
vielleicht wäre sowas hier: Farbverlauf mit PHP besser geeignet
...also Farb-Palette zwischen zwei Farben mit n Stufen erstellen (je Ebene)
dazu die $steps durch $max_deep aus de Code ersetzen
(diese Variable dann global oder im Funktionsaufruf übergeben)
hier mal das mit "Farb-Palette" in die print_tree() mit eingebaut
<?php // ----------------------------------------------------------------- // ------------------- print_tree() --- Version: 2 ----------------- function print_tree($array, $level=0, $view=1) { // -------- Ebenen Hintergrund-Farben -------- global $max_deep; $color1 = '#ACACAC'; $color2 = '#FFFFFF'; $r1=hexdec(substr($color1,1,2)); $g1=hexdec(substr($color1,3,2)); $b1=hexdec(substr($color1,5,2)); $r2=hexdec(substr($color2,1,2)); $g2=hexdec(substr($color2,3,2)); $b2=hexdec(substr($color2,5,2)); $diff_r=$r2-$r1; $diff_g=$g2-$g1; $diff_b=$b2-$b1; for ($i=1; $i<=$max_deep; $i++) { $factor = ($i / $max_deep); $r=round($r1 + $diff_r * $factor); $g=round($g1 + $diff_g * $factor); $b=round($b1 + $diff_b * $factor); $color="#" . sprintf("%02X",$r) . sprintf("%02X",$g) . sprintf("%02X",$b); $bgcolor[$i] = $color; } // -------- id-Prefix und Code-Spacer -------- $prefix = 'liste'; // ---- Prefix: ul ID ---- $cspace = "\t"; ## $cspace = ' '; $spacer = str_repeat($cspace, (($level+1)*2)); // -------- Ebene 1 --- START -------- if ($level == 0) { print "\n<ul id=\"".$prefix."_root\" style=\"background:".$color1.";\">\n"; } // -------- Baum aus Array --- START -------- foreach($array as $key => $val) { $prelevel = $level; $level++; if ( isset($val['sub']) && !empty($val['sub']) ) { $preid = $val['parent_id']; $switch_link = "<a href=\"javascript:show('".$prefix.$key.$level."')\">open/close</a>"; // -------- Listen-Element mit Unter-Ebene --- START -------- print $spacer."<li>Ebene: ".$level." --- <strong>".$val['name']."</strong> [".$switch_link."] - (ID: ".".$key.".")"; $ulcolor = 'background:'.$bgcolor[$level].''; if ($level >= $view) { $ulview = 'display:none;'; } else { $ulview = 'display:block;'; } $ulstyle = 'style="'.$ulview.' '.$ulcolor.'"'; // -------- Sub-Ebene --- START -------- print "\n".$spacer."<ul id=\"".$prefix.$key.$level."\" ".$ulstyle.">\n"; print_tree($val['sub'], $level, $view); // ---- rekursiver Funktions-Aufruf ---- print $spacer."</ul>\n"; // -------- Sub-Ebene --- ENDE -------- print $spacer."</li>\n\n"; // -------- Listen-Element mit Unter-Ebene --- ENDE -------- } else { // -------- Listen-Element ohne Unter-Ebene -------- print $spacer."<li>Ebene: ".$level." --- <strong>".$val['name']."</strong> (ID: ".$key.")</li>\n"; } $level--; } // -------- Baum aus Array --- ENDE -------- if ($level == 0) { print "</ul>\n"; } // -------- Ebene 1 --- ENDE -------- } // ----------------------------------------------------------------- ?>
PS:
leider immernoch Sub-Ebenen als rekursiver Funktions-Aufruf
---> vielleicht kann man das ja "besser" lösen ?!
und die Variavlen:
$cspace
$max_deep
$color1
$color2
kann man - je nach Belieben -auch anders setzen ,
z.B. im Funktions-Aufruf (als Parameter) oder global definieren,
... ist wohl Geschmackssache,
habs hier halt jetzt mal so "gemixed" im BSP gemacht
Beitrag zuletzt geändert: 4.9.2012 12:08:43 von plugboard -
schon ganz nett :)
aber mit der Funktion wird bei jedem Durchlauf das Farben-Array $bgcolor immer wieder neu erstellt,
das würde ich auch noch in eine extra Funktion auslagern, also nur einmal vorher "bauen"
und dann anstatt
eben das Farben-Array nehemenglobal $max_deep;
global $bgcolor;
also vorher das Array für Hintergrund-Farben erstellen
<?php // ----------------------------------------------------------------- // ---- die Variable $max_deep (int) ist aus vorherigem Script vorhanden $color1 = '#ACACAC'; $color2 = '#FFFFCC'; if (!isset($bgcolor)) { $bgcolor = tree_color_data($color1, $color2, $max_deep); } // ----------------------------------------------------------------- ?>
mit der (neuen) Funktion tree_color_data()
<?php // ----------------------------------------------------------------- // -------------------- Ebenen Hintergrund-Farben ------------------ // ----------------------------------------------------------------- function tree_color_data($color1, $color2, $max_deep) { $r1 = hexdec(substr($color1,1,2)); $g1 = hexdec(substr($color1,3,2)); $b1 = hexdec(substr($color1,5,2)); $r2 = hexdec(substr($color2,1,2)); $g2 = hexdec(substr($color2,3,2)); $b2 = hexdec(substr($color2,5,2)); $diff_r = ($r2-$r1); $diff_g = ($g2-$g1); $diff_b = ($b2-$b1); $bgcolorarr = array(); for ($i=1; $i<=$max_deep; $i++) { $factor = ($i / $max_deep); $r = round($r1 + $diff_r * $factor); $g = round($g1 + $diff_g * $factor); $b = round($b1 + $diff_b * $factor); ## $xcolor = '#' . sprintf('%02X',$r) . sprintf('%02X',$g) . sprintf('%02X',$b); $xcolor = '#' . dechex($r) . dechex($g) . dechex($b); $bgcolorarr[$i] = $xcolor; } return $bgcolorarr; } // ----------------------------------------------------------------- ?>
und dann die print_tree() Funktion mit
machen / aufrufenglobal $bgcolor;
<?php // ----------------------------------------------------------------- // ------------------- print_tree() --- Version: 3 ----------------- // ----------------------------------------------------------------- function print_tree($array, $level=0, $view=1) { global $bgcolor; // ---- Ebenen Hintergrund-Farben ---- $anzkat = 1; // ---- Kategorie Zaehler ---- $prefix = 'kat'; // ---- Prefix fuer ul ID ---- $cspace = "\t"; // ---- Quellcode Spacer ---- $spacer = str_repeat($cspace, (($level+1)*2)); // -------- Ebene 1 --- START -------- if ($level == 0) { print "\n<ul id=\"".$prefix."_root\" style=\"display:block; background:".$bgcolor[0].";\">\n"; } // -------- Baum aus Array --- START -------- foreach($array as $key => $val) { $prelevel = $level; $level++; if ( isset($val['sub']) && !empty($val['sub']) ) { $subcount = count($val['sub']); $preid = $val['parent_id']; $switch_link = "<a href=\"javascript:show('".$prefix.$key.$level."')\">open/close:</a> + ".$subcount.""; // -------- Listen-Element mit Unter-Ebene --- START -------- print $spacer."<li>Level: ".$level." --- ID: ".$key." --- (". str_pad($anzkat,2,'0',STR_PAD_LEFT) .") --- <strong>".$val['name']."</strong> [".$switch_link."] "; $anzkat++; $ulcolor = 'background:'.$bgcolor[$level].';'; if ($level >= $view) { $ulview = 'display:none;'; } else { $ulview = 'display:block;'; } $ulstyle = 'style="'.$ulview.' '.$ulcolor.'"'; // -------- Sub-Ebene --- START -------- print "\n".$spacer."<ul id=\"".$prefix.$key.$level."\" ".$ulstyle.">\n"; print_tree($val['sub'], $level, $view); // ---- rekursiver Funktions-Aufruf ---- print $spacer."</ul>\n"; // -------- Sub-Ebene --- ENDE -------- print $spacer."</li>\n\n"; // -------- Listen-Element mit Unter-Ebene --- ENDE -------- } else { // -------- Listen-Element ohne Unter-Ebene -------- print $spacer."<li>Level: ".$level." --- ID: ".$key." --- (". str_pad($anzkat,2,'0',STR_PAD_LEFT) .") --- <strong>".$val['name']."</strong></li>\n"; $anzkat++; } $level--; } // -------- Baum aus Array --- ENDE -------- if ($level == 0) { print "</ul>\n"; } // -------- Ebene 1 --- ENDE -------- } // ----------------------------------------------------------------- ?>
bei 10 Kategorien spart Dir das 9 mal den Zusammen-Bau des Hintergrund-Farben-Array
... also es muss nur 1x berechnet werden :=)
hier nochmal das ganze Script .... http://paste42.de/4179/taxonomy_tree
oder hier: http://pastebin.com/sFrLTt3b
habe es auch getestet, bei mir lief es so ganz gut.
-
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage