2016-06-22 18 views
1

ich dieses HTML-String in einem DOMElement habe:DOMElement ersetzen HTML-Wert

<h1>Home</h1> 
test{{test}} 

Ich mag diese Inhalte in einer Art und Weise ersetzen, die nur

<h1>Home</h1> 
test 

bleiben (so will ich die {{test}} entfernen).

In diesem Moment sieht mein Code wie folgt aus:

$node->nodeValue = preg_replace(
    '/(?<replaceable>{{([a-z0-9_]+)}})/mi', '' , $node->nodeValue); 

Das funktioniert nicht, weil nodeValue nicht den HTML-Wert des Knotens enthält. Ich kann nicht herausfinden, wie man die HTML-Zeichenfolge des Knotens anders als mit $node->C14N(), aber mit C14N kann ich den Inhalt nicht ersetzen. Irgendwelche Ideen, wie ich die {{test}} in einer HTML-Zeichenfolge wie folgt entfernen kann?

Antwort

1

Haben Sie die DOMDocument::saveXML Funktion versucht? (http://php.net/manual/en/domdocument.savexml.php)

Es hat ein zweites Argument $node, mit dem Sie angeben können, welcher Knoten den HTML/XML von drucken soll.

So zum Beispiel:

<?php 

$doc = new DOMDocument('1.0'); 
// we want a nice output 
$doc->formatOutput = true; 

$root = $doc->createElement('body'); 
$root = $doc->appendChild($root); 

$title = $doc->createElement('h1', 'Home'); 
$root->appendChild($title); 

$text = $doc->createTextNode('test{{test}}'); 
$text = $root->appendChild($text); 

echo $doc->saveXML($root); 

?> 

Dies wird Ihnen geben:

<body> 
    <h1>Home</h1> 
    test{{test}} 
</body> 

Wenn Sie nicht die <body> Tag tun möchten, können Sie durch alle seiner childnodes:

<?php 

foreach($root->childNodes as $child){  
    echo $doc->saveXML($child); 
} 

?> 

Dies gibt Ihnen:

<h1>Home</h1>test{{test}} 

Edit: Sie können dann ersetzen natürlich {{test}} durch die Regex, die Sie verwenden bereits:

<?php 

$xml = ''; 
foreach($root->childNodes as $child){  
    $xml .= preg_replace(
       '/(?<replaceable>{{([a-z0-9_]+)}})/mi', '', 
       $doc->saveXML($child) 
    ); 
} 

?> 

Dies gibt Ihnen:

<h1>Home</h1>test 

Anmerkung: Ich habe das nicht getestet Code, aber das sollte Ihnen die allgemeine Idee geben.

1

Das Problem besteht hauptsächlich darin, wie Sie durch das DOM navigieren, aber es gibt auch ein Problem mit Ihrer RegExp; XPath bietet tatsächlich eine Menge Flexibilität, wenn es um DOM-Manipulation geht, das ist meine bevorzugte Lösung.

Sie Angenommen, haben ein DOMDocument wie diese gebaut (ich habe einen XPath-Anhang):

$dom = new DOMDocument('1.0', 'utf-8'); 
$xpath = new DOMXPath($dom); 

$node = $dom->createElement('div'); 
$node->appendChild(
    $dom->createElement('h1', "Home") 
    ); 
$node->appendChild(
    $dom->createTextNode("test{{test}}") 
    ); 

$dom->appendChild($node); 

Sie können speziell den Textknoten des <div> mit '/div/text()' in XPath Ziel.

So {{test}} innerhalb dieses Textknoten zu ersetzen, ohne den Rest des Knotens korrumpieren, würden Sie tun:

$xpath->query('/div/text()')->item(0)->nodeValue = preg_replace(
     '/(.*){{[^}]+}}/m', 
     '$1', 
     $xpath->query('/div/text()')->item(0)->nodeValue 
); 

Etwas gewunden, aber die Ausgabe von $dom->saveXML(); ist:

<?xml version="1.0" encoding="utf-8"?> 
<div><h1>Home</h1>test</div> 

{{test}} hat entfernt den Rest intakt lassen.

+0

Ich habe nur den Knoten DOMEelement zur Zeit verfügbar, ich kann nicht das Dom oder Xpath verwenden. Oder ich sollte das Kind auch als xpath laden. – SheperdOfFire

+0

Sie könnten den Knoten einfach in ein DOMDocument mit einem "made up" Root-Knoten laden - dann extrahieren Sie einfach das ursprüngliche Element, wenn Sie es manipuliert haben. – CD001