XMLReader: Original Tag ausgeben

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • #16
    Zitat von pascal007 Beitrag anzeigen
    Aber eben: Was mach ich jetzt? Ich möchte einfach meine Custom-Tags durch das (X)HTML ersetzen das die "replace()"-Methode von dene generiert und rest des HTML-Dokuments 1:1 ausgeben... aber wie?
    DomDocument und DomXPath

    Zitat von pascal007 Beitrag anzeigen
    Wenn du Zeit hast und meine Situation in einem kurzen abstrakten XSLT-PHP-Beispiel erläutern könntest, würde ich evtl. auch noch auf den XSLT-Geschmack kommen ;-)
    Wenn du mir schon großzügigerweise anbietest, dass ich für dich kostenlos deine Arbeit erledigen darf, hättest du wenigstens ein konkretes Beispiel als Vorgabe liefern können.
    [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]

    Kommentar


    • #17
      'Ich will jetzt keine Werbung machen, aber ich vermute mal, die Templateengine Fluid (enthalten in Flow3) tut genau das, was du erreichen willst.
      Wir werden alle sterben

      Kommentar


      • #18
        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:

        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>
        Wobei "foo" in der for-Schleife folgenden Inhalt hat:

        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')
        ); 
        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.

        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>

        Kommentar


        • #19
          Zitat von pascal007 Beitrag anzeigen
          Beim DOMDocument fehlten mir die Infos ob es ein öffnendes Element ist oder ein END_ELEMENT, CDATA usw.
          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.
          [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]

          Kommentar


          • #20
            Okay hab jetzt nochmals einen Versuch gestartet mit DOMDocument und XPath. Folgendes hab ich nun:

            PHP-Code:
            $this->tplNodes $this->xPath->query('//*/tst:*');

            foreach(
            $this->tplNodes as $l) {
                
            $tagClassName $l->localName 'Tag';
                
            $tag = new $tagClassName;
                
            $newHTMLCodeStr $tag->replace($l);

            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.

            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); 

            Kommentar


            • #21
              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]

              Kommentar


              • #22
                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 ;-)):

                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 das geht ja nicht, ich brauch ja dann einen übgeordneten Node z.B. so:

                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>
                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...

                Kommentar


                • #23
                  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]

                  Kommentar


                  • #24
                    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 .

                    Kommentar


                    • #25
                      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. |(?:[^<]+)@
                      Code:
                      1. DOCTYPE
                      2. Comment
                      3. CDATA
                      4. Öffnende/Schliessende XML/HTML-Tags
                      5. Steuerzeichen
                      6. Einfacher Text
                      Der Regex funktioniert super, ausser an folgender Stelle:

                      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">
                      [...]
                      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...

                      Der Fehler muss irgendwo zwischen diesem Code liegen:

                      HTML-Code:
                      [...]Y" />
                      <!--<h1[...]
                      Kann mir vllt jemand sagen, wieso das "<" einfach verschlungen wird?
                      Zuletzt geändert von pascal007; 12.11.2011, 12:40.

                      Kommentar


                      • #26
                        Zitat von pascal007 Beitrag anzeigen
                        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).
                        Hast du loadXML oder loadHTML verwendet …?
                        (Wie gut letzteres mit HTML5 klarkommt, habe ich noch nicht ausprobiert.)

                        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.
                        Das klingt so, als hättest du vergessen die zu verwendende Zeichenkodierung richtig anzugeben.

                        Zuerst nehme ich das HTML-File mittels eines Regex auseinander:
                        Warum man das nicht tun sollte: html - RegEx match open tags except XHTML self-contained tags - Stack Overflow
                        I don't believe in rebirth. Actually, I never did in my whole lives.

                        Kommentar


                        • #27
                          Hab load() verwendet. Weil loadHTML erlaubt keine Namespaces (da es nur HTML 4.0 Compatible ist).

                          Das DomDocument habe ich so initalisiert:

                          Code:
                          $this->domReader = new DOMDocument("1.0","UTF-8");
                          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^^

                          Was soll ich denn sonst machen als HTML mit Regex auseinander zunehmen, wenn mir DOMDocument nicht die gewünschten Funktionen bietet ?
                          Zuletzt geändert von pascal007; 12.11.2011, 13:00.

                          Kommentar


                          • #28
                            Zitat von pascal007 Beitrag anzeigen
                            Hab load() verwendet. Weil loadHTML erlaubt keine Namespaces (da es nur HTML 4.0 Compatible ist).
                            Langsam musst du dich mal entscheiden, was du eigentlich willst.

                            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.

                            Was soll ich denn sonst machen als HTML mit Regex auseinander zunehmen, wenn mir DOMDocument nicht die gewünschten Funktionen bietet ?
                            Erst mal solltest du vielleicht dein Vorhaben gründlich überdenken.

                            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.

                            Kommentar


                            • #29
                              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.

                              Kommentar


                              • #30
                                Zitat von pascal007 Beitrag anzeigen
                                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.
                                Ja – wenn du das Dokument mit DOMDocument verarbeiten willst.

                                Dann werde ich das wohl bei der XHTML-Syntax belassen (alle Tags schliessen).
                                Man schließt Elemente, nicht Tags. Bitte den Unterschied klar machen.
                                Ein Web Designer hat mir letzthin gesagt, dass schliessende Tags den Browsern (genau wie der DOCTYPE) völlig egal sei.
                                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.
                                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.

                                Und das schliessen von leeren Tags hätte erst mit diesem XHTML begonnen.
                                Noch mal, Element != Tag, s.o.

                                HTML als SGML-Derivat erlaubt gewisse Elemente ohne schließendes Tag (bspw. img, br).
                                Hinzu kommt noch, On SGML and HTML:
                                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.
                                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/>

                                Mit saveHTML() bekomme ich ja quasi eine HTML5-konforme Repräsentation des DOMs und mit saveXML() ist es dann XHTML-koform.
                                So weit die Theorie.
                                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.

                                Kommentar

                                Lädt...
                                X