 |
06.09.2008, 20:30
| Nach oben
#1 | | Benutzer
Registriert seit: 16.09.2007
Beiträge: 65
| Template Engine mit XML
Hi
hab mir ne Template Engine mit XML geschrieben. Per DOM erstelle ich mir dynamisch meine XML fils und transformier sie mit XSLT zu einer XHTML seite.
Soweit so gut, mein problem liegt nur darin, wenn ich zB. irgendwo ein skript habe, was kategorien hat, das er jedes mal für die gleiche kategorie den namen anzeigt. Was er aber nicht soll. Der grund dafür ist eigentlich auch klar, ich weiss nur nicht wie ich das lösen kann.
Hier der quelle code
Template.php PHP-Code: <?php class XmlTemplate {
private $templateDir;
private $oDom;
private $oXSLT;
private $saveXML;
private $template = "";
public function __construct(){ $this->templateDir = site_path . "public/template"; $this->oDom = new DOMDocument('1.0', 'UTF-8'); $this->oXSLT = new XsltProcessor; }
public function load($filename){ $xsl = new DOMDocument;
if(!is_file($this->templateDir. DIRSEP.$filename.'.xsl')){ die("Not Found"); } $xsl->load($this->templateDir. DIRSEP.$filename.'.xsl');
$this->oXSLT->importStylesheet($xsl); }
private function generateXMLNode($data, $root, $document,$nodeName) { if(is_array($data)) { foreach($data as $key => $value) {
if(is_int($key)){ $node = $document->createElement($nodeName); } else { $node = $document->createElement($key);
} $node = $root->appendChild($node); $this->generateXMLNode($value, $node, $document,$nodeName);
} } else { $node = $document->createTextNode($data); $node = $root->appendChild($node); } }
public function assign($replace, $replacement, $nodeName=""){ $root = $this->oDom->createElement($replace); $root = $this->oDom->appendChild($root);
$this->generateXMLNode($replacement, $root, $this->oDom, $nodeName);
$this->saveXML = $this->oDom->saveXML();
}
public function out(){ echo $this->fetch(); }
public function fetch(){ $xml = new DOMDocument; $xml->loadXML($this->saveXML); $template = $this->oXSLT->transformToXML($xml) or die('Transformation error!'); return $template; } } der dazu gehörige Code mit der Abfrage PHP-Code: $this->registry['tpl']->load('templatename/test');
$db = new MySQL(); $db->query("SELECT * FROM kat "); while ($data = $db->fetchRow()) { $kat[]= $data;
$db1 = new MySQL(); $db1->query("SELECT * FROM test where kate = '".$data['kat']."'");
while($dat = $db1->fetchRow()){ $zeilen[] = $dat; }
}
$db->disconnect();
$this->registry['tpl']->assign('test',$zeilen,'news'); $this->registry['tpl']->out();
die xsl PHP-Code:
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns="http://www.w3.org/1999/xhtml" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl" exclude-result-prefixes="php"> <xsl:output method="xml" encoding="UTF-8" indent="yes" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" omit-xml-declaration="yes" /> <xsl:include href="root.xsl" /> <xsl:template match="/test"> <xsl:apply-templates select="news"/> <p><a href="index">index</a></p> </xsl:template>
<xsl:template match="news">
<p><xsl:value-of select="name"/></p> </xsl:template>
</xsl:stylesheet> Die Ausgabe sieht momentan so aus.
Kategorie 1 -bla Kategorie 1
-bla Kategorie 1 -bla Kategorie 2 -bla Kategorie 3
-bla
Aber es soll so aus sehn. Kategorie 1 -bla
-bla
-bla Kategorie 2 -bla Kategorie 3
-bla
Auf Kommentare habe ich erstmal verzichtet in der Template.php sonst würde das hier zu lange. Hoffe das der code klar ist, sonst erklär ich es noch mal.
Gruß
Alex
|
| |
08.09.2008, 01:20
| Nach oben
#2 | | Benutzer
Registriert seit: 16.09.2007
Beiträge: 65
|
hm keiner ne idee?
|
| |
08.09.2008, 11:15
| Nach oben
#3 | | Verplanter Benutzer
Registriert seit: 14.12.2004
Beiträge: 238
|
meinst Du sowas in die Richtung evtl. ? PHP-Code: foreach($data as $key => $value) {
if(is_int($key) AND $lastkey == $key ){
$node = $document->createElement($nodeName);
} else {
$node = $document->createElement($key);
}
$node = $root->appendChild($node);
$this->generateXMLNode($value, $node, $document,$nodeName);
$lastkey = $key;
}
__________________
Das Leben ist zwar bloß ein Adventure-Game, aber die Grafik ist verdammt gut.
Ich such immer noch den Cheat für unlimited money!
|
| |
08.09.2008, 12:04
| Nach oben
#4 | | Benutzer
Registriert seit: 16.09.2007
Beiträge: 65
|
Das funktinoiert leider nicht. Da kommt der fehler Code: Undefined variable: lastkey So sollte das XML file aussehn Code: <test>
<news>
<kat>test</kat>
<content>
<name>blabla</name>
</content>
<content>
<name>blabla</name>
</content>
<content>
<name>blabla</name>
</content>
</news>
<news>
<kat>bla2</kat>
<content>
<name>blabla</name>
</content>
</news>
<news>
<kat>bla3</kat>
<content>
<name>blabla</name>
</content>
</news>
</test>
Hab nun auch bissel was an der Abfrage geändert das sieht nun so aus. PHP-Code: $this->registry['tpl']->load('koosai/test'); $db = new MySQL(); $db->query("SELECT * FROM kat "); while ($data = $db->fetchRow()) { $kat[] = $data; $db1 = new MySQL(); $db1->query("SELECT * FROM test where kate = '".$data['kat']."'"); while($dat = $db1->fetchRow()){ $zeilen[] = $dat; } $test[] = array_merge($data ,$zeilen); unset($zeilen); } $this->registry['tpl']->assign('test',$test,'news'); $this->registry['tpl']->out();
Und das jetztig XML file sieht so aus wo "content" steht, steht auch news. Ist auch klar weil der key dazu auch nen int ist und das wird dann mit dem $nodeName versehn.
Geändert von Victorious (08.09.2008 um 12:08 Uhr)
|
| |
09.09.2008, 06:12
| Nach oben
#5 | | Benutzer
Registriert seit: 16.09.2007
Beiträge: 65
|
So nach stunden langer probiererei habe ich doch noch ne lösung gefunden. Ich weiss nur nicht ob die so wirklich elegant ist. Das ganze sieht nun so aus.
In der Template.php habe ich nun das hinzugefügt. PHP-Code: public function createRoot($rootname){ return $this->oDom->appendChild($this->oDom->createElement($rootname)); }
public function appendChild($parent,$nodeName,$nodeText=""){ if($nodeText != ""){ $this->node = $parent->appendChild($this->oDom->createElement($nodeName,$nodeText));
} else { $this->node = $parent->appendChild($this->oDom->createElement($nodeName)); } return $this->node; }
Die erste Methode erzeugt wie schon der Name sagt das Root Element und die zeite die ChildNodes.
Weiter hin habe ich noch die beiden methoden drin. PHP-Code: private function generateXMLNode($data, $root, $document) { if(is_array($data)) { foreach($data as $key => $value ) { $node = $document->createElement($key); $node = $root->appendChild($node); $this->generateXMLNode($value, $node, $document);
}
} else { $node = $document->createTextNode($data); $node = $root->appendChild($node); } }
public function createXmlOfAssoArray($replace, $replacement){ $root = $this->oDom->createElement($replace); $root = $this->oDom->appendChild($root);
$this->generateXMLNode($replacement, $root, $this->oDom); }
Falls ein Assoziatives array vor liegt.
Und der code der das ausführt sieht so aus. PHP-Code: $this->registry['tpl']->load('koosai/test'); $db = new MySQL(); $db->query("SELECT * FROM kat ");
$root = $this->registry['tpl']->createRoot('links');
while ($data = $db->fetchRow()) {
$kategorie = $this->registry['tpl']->appendChild($root,'kategorie'); foreach($data as $k => $v){ $this->registry['tpl']->appendChild($kategorie,$k,$v); $link = $this->registry['tpl']->appendChild($kategorie,'link'); }
$db1 = new MySQL(); $db1->query("SELECT * FROM test where kate = '".$data['kat']."'"); while($dat = $db1->fetchRow()){ foreach($dat as $key => $value){ $this->registry['tpl']->appendChild($link,$key,$value); } } } $this->registry['tpl']->out(); $db->disconnect();
|
| |
10.09.2008, 00:02
| Nach oben
#6 | | Verplanter Benutzer
Registriert seit: 14.12.2004
Beiträge: 238
|
Naja, der Fehler kommt daher das die Variable nicht dekl. wurde. PHP-Code: $lastkey = null; # hier wird sie festgelegt
foreach($data as $key => $value) {
if(is_int($key) AND $lastkey == $key ){
$node = $document->createElement($nodeName);
} else {
$node = $document->createElement($key);
}
$node = $root->appendChild($node);
$this->generateXMLNode($value, $node, $document,$nodeName);
$lastkey = $key;
}
__________________
Das Leben ist zwar bloß ein Adventure-Game, aber die Grafik ist verdammt gut.
Ich such immer noch den Cheat für unlimited money!
|
| |
10.09.2008, 19:06
| Nach oben
#7 | | Benutzer
Registriert seit: 16.09.2007
Beiträge: 65
|
selbst wenn ich sie deklariere gehts nicht.
|
| |
11.09.2008, 02:45
| Nach oben
#8 | | Verplanter Benutzer
Registriert seit: 14.12.2004
Beiträge: 238
|
Hast es ja gelöst, aber nur aus Intersse ... diese Schleife soll doch unterscheiden ob das ein Titel oder ein Untertitel wird.
Zu meinem Beispiel ist glaube ich auch das Array falsch aufgebaut. (Geschmacksache)
Ich bin davon ausgegangen das
array[titel][untertitel]
und daher die Schleife eben in der Art, wenn der letzte Titel gleich ist für nur
Untertitel hinzu ist er anders mache beides, erst Titel dann Untertitel.
abgespeckt: PHP-Code: $lastkey = null;
foreach($data as $key => $value) {
if(empty($lastkey)) OR $lastkey != $key){ #empty für den ersten
#erstelle Titel -> $key
} else {
#erstelle Untertitel -> $unit
}
$lastkey = $key;
}
oder wegen mit auch mit array([i]array([titel][untertitel]))
nur mal so als Beispiel ... PHP-Code: $lastkey = null;
foreach($data as $key => $value) {
if(empty($lastkey)) OR $lastkey != $value[0]){ #empty für den ersten
#erstelle Titel -> $value[0]
} else {
#erstelle Untertitel -> $value[1]
}
$lastkey = $value[0];
}
__________________
Das Leben ist zwar bloß ein Adventure-Game, aber die Grafik ist verdammt gut.
Ich such immer noch den Cheat für unlimited money!
Geändert von DasMööp (11.09.2008 um 02:56 Uhr)
|
| |
11.09.2008, 03:08
| Nach oben
#9 | | Benutzer
Registriert seit: 16.09.2007
Beiträge: 65
|
Das problem ist das die daten aus der Datenbank kommen. Wenn man nun die daten so abfängt. PHP-Code: while($data=$db->fetch()){ $kategorie = $data; while($dat= $db2->fetch()){ $content[] = $dat; } $all[] = array_merge($kategorie,$content); unset($content); }
sieht da array so aus Code: array
0 =>
array
'kategorie' => string 'bla'
0 =>
array
'name' => string 'blabla'
'kate' => string 'bla'
1 =>
array
'name' => string 'blabla'
'kate' => string 'bla'
2 =>
array
'name' => string 'blabla'
'kate' => string 'bla'
1 =>
array
'kategorie' => string 'bla2'
0 =>
array
'name' => string 'blabla'
'kate' => string 'bla2'
2 =>
array
'kategorie' => string 'bla3'
0 =>
array
'name' => string 'blabla'
'kate' => string 'bla3' aber ich hätte das ganze gerne so Code: array
' kategories '=>
array
'kategorie' => string 'bla'
links =>
array
'name' => string 'blabla'
'kate' => string 'bla'
array
'name' => string 'blabla'
'kate' => string 'bla'
array
'name' => string 'blabla'
'kate' => string 'bla'
'kategorie' => string 'bla2'
links =>
array
'name' => string 'blabla'
'kate' => string 'bla2'
'kategorie' => string 'bla3'
links =>
array
'name' => string 'blabla'
'kate' => string 'bla3' Aber das geht wohl nicht, wegen den gleichen keys. Und ich hab auch keine Ahnung wie man die Daten aus der Datenbank anders raus bekommen könnte.
|
| |
11.09.2008, 14:09
| Nach oben
#10 | | Verplanter Benutzer
Registriert seit: 14.12.2004
Beiträge: 238
|
ähm ... jetzt komm ich ned mit. Das Array aus der Datenbank gib das mal per print_r() aus ... bzw. da hätte ich es schon anders gemacht bei der Abfrage. PHP-Code: $this->registry['tpl']->load('koosai/test');
$db = new MySQL();
$db->query("SELECT kat FROM kat ");
while ($data = $db->fetchRow()) {
# $db1 = new MySQL(); #warum nochmal eine Verbindung ???
$db->query("SELECT id,name,link FROM test where kate = '".$data['kat']."'");
while($dat = $db->fetchRow()){
$subLink['name'] = $dat['link'];
}
# hier das array subLink sortieren zB.
$test[$data['kat']][] = $subLink;
}
$this->registry['tpl']->assign('test',$test,'news');
$this->registry['tpl']->out();
Damit müsste das Array wie folgt aussehen: Code: array 'kategorie1' =>
array 0 =>
array 'name', 'link'
array 1 =>
array 'name', 'link'
array 2 =>
array 'name', 'link'
array 'kategorie2' =>
array 0 =>
array 'name', 'link'
array 1 =>
array 'name', 'link'
PHP-Code: foreach($data as $dataKey => $dataValue) {
#erstelle Titel -> $dataKey
foreach($dataValue as $key => $value) {
#erstelle SubTitel $value[0] als Name mit $value[1] als Link
}
}
ungetestet ... keine Zeit
__________________
Das Leben ist zwar bloß ein Adventure-Game, aber die Grafik ist verdammt gut.
Ich such immer noch den Cheat für unlimited money!
Geändert von DasMööp (11.09.2008 um 14:13 Uhr)
|
| |
11.09.2008, 17:16
| Nach oben
#11 | | Benutzer
Registriert seit: 16.09.2007
Beiträge: 65
|
Grml das macht langsam keinen spass mehr ^^.
Also dein code hat ned ganz geklappt musste es ein wenig umstellen sieht nun so aus. PHP-Code: $this->registry['tpl']->load('koosai/test'); $db = new MySQL(); $db->query("SELECT * FROM kat ");
while ($data = $db->fetchRow()) {
$db1 = new MySQL(); //Weil mir sonst das query überschrieben wird. $db1->query("SELECT * FROM test where kate = '".$data['kat']."'"); while($dat = $db1->fetchRow()){ $subLink[]['name'] = $dat['name'];
}
$test[$data['kat']]=$subLink; unset($subLink);
}
$this->registry['tpl']->assign('test',$test); $this->registry['tpl']->out();
PHP-Code: foreach($data as $dataKey => $dataValue) {
if(is_int($dataKey)){ foreach($dataValue as $key => $value){ $root->appendChild($document->createElement($key,$value)); } } else{ $node = $root->appendChild($document->createElement('kategorie',$dataKey)); $node = $root->appendChild($document->createElement('content')); foreach($dataValue as $key => $value) {
foreach($value as $k => $v){
$node-> | |