2016-06-22 6 views
1

J'ai cette chaîne HTML dans un DOMElement:DOMElement remplacer la valeur HTML

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

Je veux remplacer ce contenu d'une manière que seuls

<h1>Home</h1> 
test 

reste (donc je veux enlever le {{test}}).

En ce moment, mon code ressemble à ceci:

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

Cela ne fonctionne pas parce que nodeValue ne contient pas la valeur HTML du nœud. Je ne peux pas comprendre comment obtenir la chaîne HTML du noeud autre que l'utilisation $node->C14N(), mais en utilisant C14N je ne peux pas remplacer le contenu. Des idées comment je peux supprimer le {{test}} dans une chaîne HTML comme ça?

Répondre

1

Avez-vous essayé la fonction DOMDocument::saveXML? (http://php.net/manual/en/domdocument.savexml.php)

Il a un deuxième argument $node avec lequel vous pouvez spécifier quel noeud pour imprimer le HTML/XML de.

Ainsi, par exemple:

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

?> 

Cela vous donnera:

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

Si vous ne voulez pas la balise <body>, vous cycle pourrait par tous ses childNodes:

<?php 

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

?> 

Cela vous donnera:

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

Edit: vous pouvez remplacer des cours {{test}} par le regex que vous utilisez déjà:

<?php 

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

?> 

Cela vous donnera:

<h1>Home</h1>test 

Note: Je ne l'ai pas testé la code, mais cela devrait vous donner l'idée générale.

1

Le problème réside principalement dans la façon dont vous naviguez dans le DOM, mais il y a aussi un problème avec votre RegExp; XPath offre en fait beaucoup de flexibilité quand il s'agit de manipulation DOM, c'est donc ma solution préférée.

En supposant que vous avez un DOMDocument construit comme ça (j'ai joint un XPath):

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

Vous pouvez cibler spécifiquement le noeud texte de cette <div> avec '/div/text()' dans XPath.

Donc, pour remplacer {{test}} dans ce nœud de texte sans altérer le reste du nœud, vous feriez:

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

Un peu alambiquée, mais la sortie de $dom->saveXML(); est:

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

{{test}} a été enlevé laissant le reste intact.

+0

J'ai seulement le noeud DOMElement disponible pour l'instant, je ne peux pas utiliser dom ou xpath. Ou je devrais charger l'enfant comme xpath aussi bien. – SheperdOfFire

+0

Vous pouvez simplement charger le noeud dans un DOMDocument avec un noeud «root» «constitué» - puis extraire simplement l'élément d'origine lorsque vous avez fini de le manipuler. – CD001