2017-02-11 17 views
0

У меня есть PHP-скрипт, который использует DOMDocument и DOMXPath для поиска и замены кодов слияния в HTML-шаблоне. Простой пример может быть:Как вставить HTML в текстовый узел с DOMNode в PHP

<html> 
    <head> 
    <title>Title</title> 
    </head> 
    <body> 
    <p>Hello {greeting}!</p> 
    <table><tr> 
     <td>Details:</td> 
     <td>{details}</td> 
    </tr></table> 
    </body> 
</html> 

Следующего кодом замещенных полей на основе ассоциативного массива, где ключ соответствует полю слияния:

private function substituteFields (DOMNode $node, $fields) 
{ 
    $x = new DOMXPath ($node->ownerDocument); 
    foreach ($fields as $field => $value) 
    { 
     $query = $x->query (".//text()[contains(., '{" . $field . "}')]", $node); 

     foreach ($query as $subnode) 
     { 
      $subnode->nodeValue = str_replace ("{" . $field . "}", $value, $subnode->nodeValue); 
     } 
    } 
} 

Это работает хорошо.

Однако некоторые коды слияния потребуется HTML подставляются в них:

$fields ['greeting'] = "Joe Soap"; 
$fields ['details'] = "<div class='details'>Details here</div>"; 

Замещение происходит, но в настоящее время HTML спасся, что, вероятно, разумная идея в большинстве случаев.

Могу ли я обойти это?

ответ

0

У меня это немного неуклюже, но сейчас это работает. Если будут лучшие решения, я с радостью изменю свой ответ!

По существу, это ищет признак открытия «<» в тексте подстановки. Если он находит один, он вызывает метод подстановки HTML, который я изменил из этого question, answer and comments.

У этого есть ограничение в том, что он не может заменить средний узел HTML. Например, следующий не будет работать:

<p>Here is a bit of {html_code}</p> 

Но это может быть сделано, чтобы работать так:

<p>Here is a bit of <span>{html_code}</span></p> 

Вот измененный код:

private function substituteFields (DOMNode $node, $fields) 
{ 
    $x = new DOMXPath ($node->ownerDocument); 
    foreach ($fields as $field => $value) 
    { 
     $query = $x->query (".//text()[contains(., '{" . $field . "}')]", $node); 

     foreach ($query as $subnode) 
     { 
      $replace = str_replace ("{" . $field . "}", $value, $subnode->nodeValue); 

      if (substr ($replace, 0, 1) != "<") 
      { 
       $subnode->nodeValue = $replace; 
      } 
      else 
      { 
       $this->appendHTML ($subnode, $replace); 
      } 
     } 
    } 
} 

private function appendHTML (DOMNode $parent, $source) 
{ 
    $tmpDoc = new DOMDocument(); 
    $tmpDoc->loadHTML ($source); 
    foreach ($tmpDoc->getElementsByTagName ('body')->item (0)->childNodes as $node) 
    { 
     $importedNode = $parent->ownerDocument->importNode ($node, true); 
     $parent->parentNode->replaceChild ($importedNode, $parent); 
    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^