XMLReader: Original Tag ausgeben
Collapse
X
-
[COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
Super, danke!
[/COLOR]
-
'Ich will jetzt keine Werbung machen, aber ich vermute mal, die Templateengine Fluid (enthalten in Flow3) tut genau das, was du erreichen willst.
Comment
-
Ich habe es nun mit XMLReader soweit hinbekommen.
Beim DOMDocument fehlten mir die Infos ob es ein öffnendes Element ist oder ein END_ELEMENT, CDATA usw.
Das Beispiel wäre folgendes:
Wobei "foo" in der for-Schleife folgenden Inhalt hat:HTML Code:<!DOCTYPE html> <!--[if lt IE 7 ]> <html class="no-js ie6" lang="de" xmlns:tst="TplTag"><![endif]--> <!--[if IE 7 ]><html class="no-js ie7" lang="de" xmlns:tst="TplTag"><![endif]--> <!--[if IE 8 ]><html class="no-js ie8" lang="de" xmlns:tst="TplTag"><![endif]--> <!--[if IE 9 ]><html class="no-js ie9" lang="de" xmlns:tst="TplTag"><![endif]--> <!--[if gt IE 8]><!--> <html class="no-js" lang="de" xmlns:tst="TplTag"> <!--<![endif]--> <head> <title>Test</title> <meta encoding="UTF-8" /> <link rel="stylesheet" type="text/css" href="/css/style.css" /> <style type="text/css"> body { background-color:#eee; font-family:Arial,Verdana,"Times New Roman"; } .entry { background-color:#fff; border:2px solid #ccc; padding:15px; margin-bottom:15px; } </style> </head> <body class="no-js"> <h1>Newest news</h1> <p><tst:text value="info" /></p> <tst:for value="foo" var="bar"> <div class="entry"> <h2><tst:text value="bar[title]" /></h2> <p><tst:text value="bar[content]" /></p> <hr /> <p>Geschrieben am: <tst:date format="d.m.Y, H:i:s" /></p> </div> </tst:for> <tst:loadSubTpl tplfile="tpl_footer.html" /> <!--<h1>if ... else</h1> <tst:if cond=""> <p>Ich bin 0</p> </tst:if> <tst:else> <p>Ich bin 1</p> </tst:else>--> <script type="text/javascript"> function helloWorld() { alert('hello world'); } </script> <![CDATA[Das wird eh nicht gezeigt!]]> </body> </html>
Ich möchte dich nicht meine Arbeit machen lassen ;-). Hab ja jetzt eine Klasse die quasi schon funktioniert aber noch verbesserungswürdig wäre... sie schafft allerdings dieses Beispiel Template zu parsen.PHP Code:$testData = array(
array('title' => 'first title', 'content' => 'first content here')
,array('title' => 'second title', 'content' => 'second content here')
,array('title' => 'noch ein title', 'content' => 'blubb blah')
);
Wobei leider viel von der Formatierung verloren geht
.
Mein Resultat sieht wie folgt aus:
HTML Code:<!doctype html> <!--[if lt IE 7 ]> <html class="no-js ie6" lang="de" xmlns:tst="TplTag"><![endif]--> <!--[if IE 7 ]><html class="no-js ie7" lang="de" xmlns:tst="TplTag"><![endif]--> <!--[if IE 8 ]><html class="no-js ie8" lang="de" xmlns:tst="TplTag"><![endif]--> <!--[if IE 9 ]><html class="no-js ie9" lang="de" xmlns:tst="TplTag"><![endif]--> <!--[if gt IE 8]><!--><html class="no-js" lang="de"> <!--<![endif]--> <head> <title>Test</title> <meta encoding="UTF-8"/> <link rel="stylesheet" type="text/css" href="/css/style.css"/> <style type="text/css"> body { background-color:#eee; font-family:Arial,Verdana,"Times New Roman"; } .entry { background-color:#fff; border:2px solid #ccc; padding:15px; margin-bottom:15px; } </style> </head> <body class="no-js"> <h1>Newest news</h1> <p>Here you'll find only the hottest news around!</p> <div class="entry"> <h2>first title</h2> <p>first content here</p> <hr/> <p>Geschrieben am: 10.11.2011, 21:27:38</p> </div> <div class="entry"> <h2>second title</h2> <p>second content here</p> <hr/> <p>Geschrieben am: 10.11.2011, 21:27:38</p> </div> <div class="entry"> <h2>noch ein title</h2> <p>blubb blah</p> <hr/> <p>Geschrieben am: 10.11.2011, 21:27:38</p> </div> <p>Haha i bi nur de footer. So glatt! Und ich bin included worde am: 10.11.2011, 21:27:38</p> <!--<h1>if ... else</h1> <tst:if cond=""> <p>Ich bin 0</p> </tst:if> <tst:else> <p>Ich bin 1</p> </tst:else>--> <script type="text/javascript"> function helloWorld() { alert('hello world'); } </script> <![CDATA[Das wird eh nicht gezeigt!]]> </body> </html>
Comment
-
Du bringst da etwas durcheinander. In XML (Quellcode) gibt es Empty-Element-Tags, öffnende Tags und schließende Tags. Im DOM (Hierarchisches Objektorientiertes Modell) gibt es nur Elementknoten (und andere Knoten). Darum wird dir DomDocument niemals sagen können, ob etwas ein öffnendes oder ein schließendes Tag ist, da es im DOM keine Tags gibt. Den Knotentyp (Element, Attribut, Textknoten, CDATA-Section, Kommentar, PI, …) kannst du aber immer über die nodeType-Eigenschaft eines Knotens abrufen.Originally posted by pascal007 View PostBeim DOMDocument fehlten mir die Infos ob es ein öffnendes Element ist oder ein END_ELEMENT, CDATA usw.[COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
Super, danke!
[/COLOR]
Comment
-
Okay hab jetzt nochmals einen Versuch gestartet mit DOMDocument und XPath. Folgendes hab ich nun:
Ich müsste jetzt, wie oben im Code, in der foreach-Schleife mit $l->localName den Tag-name holen, die replace()-Method des entsprechenden Tags aufrufen und ihr den Node $l mitgeben. Dann generiert mir die Methode den neuen HTML-Quelltext der an Stelle des Template-Tags steht.PHP Code:$this->tplNodes = $this->xPath->query('//*/tst:*');
foreach($this->tplNodes as $l) {
$tagClassName = $l->localName . 'Tag';
$tag = new $tagClassName;
$newHTMLCodeStr = $tag->replace($l);
}
Aber dann wie weiter? Wie bekomme ich den $newHTMLCodeStr in ein Node? Der Replace wäre dann nicht mehr schwer:
PHP Code:$newNode = irgendwieAlsNode($newHTMLCodeStr);
$l->parentNode->replaceChild($newNode,$l);
Comment
-
Wieso modelst du im DOM mit Strings rum?
Stell es dir mal so vor: Du hast eine Birke, die hat einen Stamm, Äste, noch mehr Äste, Zweige und irgendwann Blätter. Diese Birke ist das DOM. Jetzt machst du ein Foto von der Birke, das du überall mit hinnehmen, austauschen, kopieren, verschenken und vieles andere kannst. Dieses Bild ist eine grafische Repräsentation der Birke, aber nicht die Birke selbst. Wenn du ein DOM speicherst, also in XML-Code umwandelst, ist dieser Code das Foto von dem Dokumentbaum. Wenn du jetzt an der Birke rumwerkeln willst (nehmen wir mal an das ginge im echten Leben) und Äste, Zweige und Blätter hinzufügst, absägst und vertauschst, dann machst du das an der Birke und klebst nicht irgendwelche Teile des Fotos an den Baum. Genausowenig hantierst du mit XML-Code (als String) herum, wenn du an der objektorientierten DOM-Struktur herumbastelst.
Erzeuge die benötigten Elemente und hänge sie ins Dokument ein. Das auf diese Weise geänderte Dokument gibst du am Ende zu XML-Code konvertiert an den Browser (so wie du von der fertig gestalteten Birke ein Foto an deine Freunde schickst).[COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
Super, danke!
[/COLOR]
Comment
-
Gut, also keine Strings. Alles klar. Dann geb ich den Node der replace-Methode des Tags und sagen wir mal der liefert dann folgender Node (schreib ihn jetzt mal als String ;-)):
Aber das geht ja nicht, ich brauch ja dann einen übgeordneten Node z.B. so:Code:<h2>Titel 1</h2> <p>Text 1</p> <hr /> <p>Geschrieben am: 11.11.2011</p> <h2>Titel 2</h2> <p>Text 2</p> <hr /> <p>Geschrieben am: 10.11.2011</p> <h2>Titel 3</h2> <p>Text 3</p> <hr /> <p>Geschrieben am: 09.11.2011</p>
Aber wenn ich dann diesen Node mit der For-Schleife ersetze habe ich den <forReplace>-Tag auch im DOM drin, will ja aber eigentlich nur das dazwischen...Code:<forReplace> <h2>Titel 1</h2> <p>Text 1</p> <hr /> <p>Geschrieben am: 11.11.2011</p> <h2>Titel 2</h2> <p>Text 2</p> <hr /> <p>Geschrieben am: 10.11.2011</p> <h2>Titel 3</h2> <p>Text 3</p> <hr /> <p>Geschrieben am: 09.11.2011</p> </forReplace>
Comment
-
Es gibt mehrere Möglichkeiten, das zu verhindern. Hier mal zwei davon:
a) Du fügst jedes erzeugte Element mit insertBefore vor dem Template-Knoten ein und löschst ihn am Ende.
b) Du erzeugst ein DomDocumentFragment, packst die Elemente dort rein (appendChild) und ersetzt den Template-Knoten mit diesem Fragment (replaceChild).
Kann es sein, dass du dich bisher viel zu wenig mit XML und DOM beschäftigt hast? Wenn man ein XML-basiertes Templatesystem schreiben will, sollte man doch wenigstens ein paar Grundlagen drauf haben.[COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
Super, danke!
[/COLOR]
Comment
-
Doch mit XML hab ich mich schon viel beschäftigt aber zugegeben nicht mit der Manipulation eines DOM-Models ;-).
Aber jetzt habe ich mich intensiv damit beschäftigt und hab nun alles hinbekommen
. Die Template-Engine läuft und ist nun erst noch codemässig kleiner geworden als mit XML-Reader und weitaus flexibler.
@AmicaNoctis: Tausend Dank für deine super Hilfe!
Hatte es zuerst nicht geglaubt, aber die zwei Stichworte: DOMDocument und DomXPath sind des Rätsels Lösung, wenn man sich mal damit beschäftigt
.
Comment
-
Okay es ist doch noch nicht alles in Ordnung. Und zwar muss man valides XML in den DOMDocument laden. Ansonsten stribt er ab. Also z.B. bei nicht geschlossenen Tags (was ja bei HTML5 wieder zulässig ist). Zudem gibt mir saveHTML() bzw. saveXML() das Dokument nicht 1:1 zurück. z.B. wandelt es Umalute (ä,ö,ü,etc.) in Entities bei HTML bzw Hex in XML um.
Deshalb habe ich mich nun an einem eigenen "DOMDocument" versucht, welches diese Restriktionen aufhebt. Zuerst nehme ich das HTML-File mittels eines Regex auseinander:
Code:1. @(?:<!DOCTYPE(.*?)>) 2. |(?:<!--.*?-->) 3. |(?:<![CDATA[.*?]]>) 4. |(?:<(/)?(\\w+\:)?(\\w+)\\s*(.*?)\\s*(/)?\\s*>) 5. |(?:[\\t|\\n|\\r\\n]+) 6. |(?:[^<]+)@
Der Regex funktioniert super, ausser an folgender Stelle:Code:1. DOCTYPE 2. Comment 3. CDATA 4. Öffnende/Schliessende XML/HTML-Tags 5. Steuerzeichen 6. Einfacher Text
Hier geht mir das startende "<" von "<!--<h1>if ... else</h1>[...]" verloren. Irgendwie wird das verschluckt und es taucht nirgendwo mehr auf... folglich wird dann der ganze Kommentar-Block nicht mehr als Kommentar angesehen sondern als Tags- und Text-Nodes...HTML Code:[...] Heute ist der: <tst:date format="d.m.Y" /> <!--<h1>if ... else</h1> <tst:if cond=""> <p>Ich bin 0</p> </tst:if> <tst:else> <p>Ich bin 1</p> </tst:else>--> <script type="text/javascript"> [...]
Der Fehler muss irgendwo zwischen diesem Code liegen:
Kann mir vllt jemand sagen, wieso das "<" einfach verschlungen wird?HTML Code:[...]Y" /> <!--<h1[...]
Last edited by pascal007; 12-11-2011, 13:40.
Comment
-
Hast du loadXML oder loadHTML verwendet …?Originally posted by pascal007 View PostOkay es ist doch noch nicht alles in Ordnung. Und zwar muss man valides XML in den DOMDocument laden. Ansonsten stribt er ab. Also z.B. bei nicht geschlossenen Tags (was ja bei HTML5 wieder zulässig ist).
(Wie gut letzteres mit HTML5 klarkommt, habe ich noch nicht ausprobiert.)
Das klingt so, als hättest du vergessen die zu verwendende Zeichenkodierung richtig anzugeben.Zudem gibt mir saveHTML() bzw. saveXML() das Dokument nicht 1:1 zurück. z.B. wandelt es Umalute (ä,ö,ü,etc.) in Entities bei HTML bzw Hex in XML um.
Warum man das nicht tun sollte: html - RegEx match open tags except XHTML self-contained tags - Stack OverflowZuerst nehme ich das HTML-File mittels eines Regex auseinander:I don't believe in rebirth. Actually, I never did in my whole lives.
Comment
-
Hab load() verwendet. Weil loadHTML erlaubt keine Namespaces (da es nur HTML 4.0 Compatible ist).
Das DomDocument habe ich so initalisiert:
Müsste doch eigentlich stimmen? das HTML-File das ich lade ist auch UTF-8 (without BOM). EDIT: Umlaute gelöst -> das PHP-Script müsste vllt auch noch UTF-8 sein^^Code:$this->domReader = new DOMDocument("1.0","UTF-8");
Was soll ich denn sonst machen als HTML mit Regex auseinander zunehmen, wenn mir DOMDocument nicht die gewünschten Funktionen bietet
?
Last edited by pascal007; 12-11-2011, 14:00.
Comment
-
Langsam musst du dich mal entscheiden, was du eigentlich willst.Originally posted by pascal007 View PostHab load() verwendet. Weil loadHTML erlaubt keine Namespaces (da es nur HTML 4.0 Compatible ist).
Entweder willst du XML-kompatibles HTML5 – dann kannst du kein Problem mit nicht geschlossenen Elementen haben; nicht-Wohlgeformheit der Eingabedaten steht dann überhaupt nicht mehr zur Debatte.
Oder du willst HTML5 einfach nur mit HTML-Syntax – dann gibt es aber keine Namespaces.
Erst mal solltest du vielleicht dein Vorhaben gründlich überdenken.Was soll ich denn sonst machen als HTML mit Regex auseinander zunehmen, wenn mir DOMDocument nicht die gewünschten Funktionen bietet
?
Wieso meint jeder Hinz und Kunz, eine eigene Template-Engine schreiben zu müssen – noch dazu meist schon dann, wenn die nötigen Kenntnisse offenbar noch nicht wirklich vorhanden sind?
PHP selbst ist schon eine Template-Sprache. Wenn man die nicht verwenden will – weil man nicht-Programmierern nicht die Möglichkeit geben will, zu viel „Schaden“ anrichten zu können o.ä. – dann gibt es zahlreiche weitere Template-Systeme, die von erfahrenen Leuten entwickelt wurden, die sich in der Praxis bewährt haben, die gut durchdacht und getestet sind.
Warum da unbedingt und immer wieder Leute auf Teufel komm raus ihr eigenes Ding kochen wollen, leuchtet mir nicht ein.
Zumal klar sein sollte, dass das in 99% der Fälle eher ein Schuss in den Ofen werden dürfte, wenn man da einfach mal naiv mit „da nehme ich mir jetzt ein paar reguläre Ausdrücke, und dann wird das schon“ rangeht …
Mein gut gemeinter Ratschlag lautet: Lass’ den Murks bleiben.
Schau dich stattdessen unter den verfügbaren Template-System um, welches davon am ehesten zu deinen Anforderungen passt, und ggf. gemäß deinen Wünschen konfigurierbar ist was den Umfang angeht.I don't believe in rebirth. Actually, I never did in my whole lives.
Comment
-
Gut das mit dem Regex mag nicht die beste Idee gewesen sein ;-). Der Hauptantrieb war/ist einfach, dass es mich interessiert (hat). Und ich hab ja auch wieder viel dazugelernt jetzt über den Verlauf des Threads. Das spricht ja schonmal dafür ;-).
Aber b2t: Das heisst also entweder muss ich mir etwas anderes für meine "CustomTags" einfallen lassen als Namespaces oder dem Ersteller des Templates XHTML-Syntax aufzwingen.
Dann werde ich das wohl bei der XHTML-Syntax belassen (alle Tags schliessen). Ein Web Designer hat mir letzthin gesagt, dass schliessende Tags den Browsern (genau wie der DOCTYPE) völlig egal sei. Und das schliessen von leeren Tags hätte erst mit diesem XHTML begonnen.
Ich habe bisher die Tags aber immer geschlossen und werde es auch weiterhin tun.
Mit saveHTML() bekomme ich ja quasi eine HTML5-konforme Repräsentation des DOMs und mit saveXML() ist es dann XHTML-koform.
Comment
-
Ja – wenn du das Dokument mit DOMDocument verarbeiten willst.Originally posted by pascal007 View PostAber b2t: Das heisst also entweder muss ich mir etwas anderes für meine "CustomTags" einfallen lassen als Namespaces oder dem Ersteller des Templates XHTML-Syntax aufzwingen.
Man schließt Elemente, nicht Tags. Bitte den Unterschied klar machen.Dann werde ich das wohl bei der XHTML-Syntax belassen (alle Tags schliessen).
Wenn die Browser lediglich einen HTML-TagSoup-Parser benutzen, ist ihnen tatsächlich vieles „egal“. Allerdings kann die Fehlerkorrektur, die sie dann ggf. anwenden (müssen), zu unterschiedlichen Ergebnissen führen.Ein Web Designer hat mir letzthin gesagt, dass schliessende Tags den Browsern (genau wie der DOCTYPE) völlig egal sei.
Erst mit HTML5 wird auch der Fehlerkorrekturalgorithmus standardisiert. Am besten fährt man aber natürlich immer, wenn man Fehlerkorrektur gar nicht erst nötig macht.
Und wenn dein „Web Designer” tatsächlich gesagt haben sollte, auch der Doctype wäre „völlig egal“, und damit auch gemeint haben sollte, dass er auch komplett verzichtbar wäre – dann hat er keine Ahnung von seinem Job. Stichwort: Quirks Mode.
Noch mal, Element != Tag, s.o.Und das schliessen von leeren Tags hätte erst mit diesem XHTML begonnen.
HTML als SGML-Derivat erlaubt gewisse Elemente ohne schließendes Tag (bspw. img, br).
Hinzu kommt noch, On SGML and HTML:
XML hingegen erlaubt keine nicht geschlossenen Elemente – was aber nicht heißt, dass es auch ein schliessendes Tag braucht, sondern das Element kann im öffnenden Tag gleich als beendet gekennzeichnet werden, wenn es inhaltsleer ist – <element/>Some HTML element types allow authors to omit end tags (e.g., the P and LI element types). A few element types also allow the start tags to be omitted; for example, HEAD and BODY. The HTML DTD indicates for each element type whether the start tag and end tag are required.
So weit die Theorie.Mit saveHTML() bekomme ich ja quasi eine HTML5-konforme Repräsentation des DOMs und mit saveXML() ist es dann XHTML-koform.
In der Praxis lauern natürlich Browser-bedingte Fallstricke. Wenn dein HTML5-Dokument bspw. vom IE als HTML verarbeitet wird (also nicht mit einem HTML5-konformen Parser), wirst du bspw. mit nicht mit schließendem Tag(!) versehenen SCRIPT-Elementen hübsche kleine Wunder erleben …I don't believe in rebirth. Actually, I never did in my whole lives.
Comment
Moderatorin
Comment