Problem mit DOMDocument

02/01/2013 17:28 Whoknowsit#1
Moin,

ich habe ein Problem mit DOMDocument. Ich möchte gerne mailto Hyperlinks verändern, jedoch wandelt DOMDocument meine Tags in htmlentities um, was zwar von der Funktionsweise korrekt ist, aber nicht gewollt.

Wie kann ich das Problem lösen?
02/01/2013 18:13 MrPuschel#2
Das Script arbeitet völlig normal. Du hast einen Denkfehler darin. Erstelle erst deinen <a/> node und danach deinen <span/> node, hänge dann den <span/> node an den <a/> node an.

[Only registered and activated users can see links. Click Here To Register...]

Im Moment erstellst du einen <a/> node und füllst ihn mit Text.

EDIT: Das ist allgemein ziemlicher clusterfuck was du da gemacht hast. Du arbeitest dort ja mit einem invaliden Dokument. DOMDocument ist dafür gedacht mit validen Dokumenten zu arbeiten, nicht mit Teilen davon. Das was du machen möchtest kannst du ohne Probleme erreichen indem du einen String lädst und diesen mit [Only registered and activated users can see links. Click Here To Register...] bearbeitest.
02/01/2013 18:33 Whoknowsit#3
Danke, aber ich steig gerade absolut nicht durch :(

Mein Problem liegt ja zZt. darin, dass ich den Text, also den nodeValue verändern möchte. Zum Einen möchte ich $matches[0] umdrehen (strrev()) und zum Anderen das Ganze mit einem Span der Klasse "bla" umschließen.

Die Hyperlinks existieren bereits und ich kann nur so (oder mittels Regex?) die entsprechenden Änderungen daran vornehmen.

Wohlmöglich reden wir aber auch aneinander vorbei :D

EDIT:

Das da ist nur ein Beispiel, um mein Problem zu verdeutlichen. Im Original lade ich ein komplettes (valides) HTML Dokument.
02/01/2013 19:07 MrPuschel#4
Hier mal ein Beispiel:

PHP Code:
<?php 

$xml 
= new DOMDocument(); 
$xml->loadHTML('<html><head></head><body><a href="mailto:[Only registered and activated users can see links. Click Here To Register...]">[Only registered and activated users can see links. Click Here To Register...]</a></body></html>'); 

$link $xml->getElementsByTagName('a');

$newspan $xml->createElement('span','');

$newspan->appendChild($link->item(0));

$xml->appendChild($newspan);

$string $xml->saveHTML(); 

echo 
$string;

?>
02/01/2013 19:22 Whoknowsit#5
Danke. So etwas ähnliches hatte ich heute bereits probiert

Das funktioniert leider nicht:

Quote:
Call to undefined method DOMElement::item()
Aber selbst wenn es funktionieren würde, sehe ich da ein Problem, denn wenn der "Text" (und das war der Grundgedanke) mehr als nur die Mailadresse enthält (z.B. noch ein <img/>), ist der Kram auch weg.

Ich möchte lediglich eine eventuell vorhandene Mailadresse innerhalb des "Texts" entsprechend verändern. Alles Andere soll unberührt bleiben.
02/01/2013 19:50 MrPuschel#6
Die Fehlermeldung sagt dir genau was nicht funktioniert. Du musst sie nur lesen. ;) Du kannst dir mit [Only registered and activated users can see links. Click Here To Register...] deine Objekte zwecks debuggen ausgeben lassen.

Mit getElementsByTagName bekommst du eine NodeList auf dessen erstes Element du mit item(0) zugreifst. Da du bereits mit einer for each durch die NodeList iterierst und jedes Element als $link erhälst , hast du bereits die einzelnden DOMElement Objects.

Dein Problem sehe ich nicht, du hängst nur an und ersetzt nicht. Du solltest dir aber überlegen ob das wirklich die Lösung ist die du benutzen möchtest. Mit Javascript ist das ein Einzeiler.
02/01/2013 20:13 Whoknowsit#7
Quote:
Die Fehlermeldung sagt dir genau was nicht funktioniert. Du solltest mal anfangen sie zu lesen anstatt das Hirn auszuschalten sobald eine Fehlermeldung auftaucht Du kannst dir mit print_r() deine Objekte zwecks debuggen ausgeben lassen.
Ich bin ja nicht völlig bescheuert. Mittlerweile bin ich die Fehlermeldung schon los.

Quote:
Dein Problem sehe ich nicht, du hängst nur an und ersetzt nicht.
In meinem 1. Code im 1. Post tu ich genau dies nicht. Ich suche innerhalb von $link->nodeValue, also dem "Text" des Hyperlinks nach einer Mailadresse (mit Hilfe des Regex) und ersetze diese.

Und wie ich oben bereits schrieb, funktioniert das auch, nur mit dem Problem, dass an Stelle von

HTML Code:
<a href="x.php?a=[Only registered and activated users can see links. Click Here To Register...]"><span class="bla">dlt.rab@oof</span></a>
eben das heraus kommt:

HTML Code:
<a href="x.php?a=[Only registered and activated users can see links. Click Here To Register...]"><span class="bla">dlt.rab@oof</span></a>
Um mein Vorhaben noch einmal zu erklären:

Ich möchte sämtliche Hyperlinks einer Webseite auf mailto-Links untersuchen und diese Links wiederum möchte ich verändern (href und Text).

Dem href soll einfach x.php?a= vorangestellt werden und im Text soll die Mailadresse (falls vorhanden) ersetzt werden. Befinden sich im Link weitere "Texte", Bilder oder dergleichen, sollte dies kein Problem sein, da nur die Mailadresse verändert werden soll.

Ursprünglich habe ich das mit Hilfe eines Regex probiert. Das funktionierte auch, aber nur bis zu einem gewissen Punkt, da ich von Regulären Ausdrücken nicht allzu viel Ahnung habe.
02/01/2013 20:48 MrPuschel#8
Lade dein Dokument.
Suche alle Elemente auf die zutrifft das sie vom Typ <a/> sind.
Für jedes Element:
- Hole dir das Attribut.
- Hole dir den Inhalt des Elements.
- Lege ein neues Element span an.
- Lege ein neues Element a an.
- Fülle den neuen Link.
- Ersetze den alten Link mit dem neuen Link indem du die Referenz auf das Elternelement nutzt.
Repeat.

Du kannst natürlich auch das alte a aushängen, es an einen span einhängen und es wieder einhängen. Unten ein Beispiel für ein Element mit neuem Element und replace.


PHP Code:
<?php  

$xml 
= new DOMDocument();  
$xml->loadHTML('<html><head></head><body><a href="mailto:[Only registered and activated users can see links. Click Here To Register...]">[Only registered and activated users can see links. Click Here To Register...]</a></body></html>');  


$link $xml->getElementsByTagName('a')->item(0);

$newSpan $xml->createElement('span');
$newLink $xml->createElement('a',$link->nodeValue);
$newSpan->appendChild($newLink);

$link->parentNode->replaceChild($newSpan$link); 

echo 
$xml->saveHTML();  

?>