Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/231.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何将元素添加到文本节点的中间';s文本?_Php_Xpath_Domdocument - Fatal编程技术网

Php 如何将元素添加到文本节点的中间';s文本?

Php 如何将元素添加到文本节点的中间';s文本?,php,xpath,domdocument,Php,Xpath,Domdocument,给定以下HTML: $content = '<html> <body> <div> <p>During the interim there shall be nourishment supplied</p> </div> </body> </html>'; $content='1!' 在此期间,应提供营养 '; 如何将其更改为以下HTML: <html> <b

给定以下HTML:

$content = '<html>
 <body>
  <div>
   <p>During the interim there shall be nourishment supplied</p>
  </div>
 </body>
</html>';
$content='1!'
在此期间,应提供营养

';
如何将其更改为以下HTML:

<html>
 <body>
  <div>
   <p>During the <span>interim</span> there shall be nourishment supplied</p>
  </div>
 </body>
</html>

在此期间,应提供营养

我需要使用DomDocument来执行此操作。以下是我尝试过的:

$dom = new DomDocument();
$dom->loadHTML($content);
$dom->preserveWhiteSpace = false;
$xpath = new DOMXpath($dom);
$elements = $xpath->query("//*[contains(text(),'interim')]");
if (!is_null($elements)) {
 foreach ($elements as $element) {
   $text = $element->nodeValue;
   $element->nodeValue = str_replace('interim','<span>interim</span>',$text);
 }
}
echo $dom->saveHTML();
$dom=newdomdocument();
$dom->loadHTML($content);
$dom->preserveWhiteSpace=false;
$xpath=newdomxpath($dom);
$elements=$xpath->query(“/*[contains(text(),'middial')]”);
如果(!为null($elements)){
foreach($elements作为$element){
$text=$element->nodeValue;
$element->nodeValue=str_replace('middial','middial',$text);
}
}
echo$dom->saveHTML();
但是,这会输出文本html实体,以便在浏览器中呈现如下内容:

During the <span>interim</span> there shall be nourishment supplied
在此期间,应提供营养

我想应该使用<代码> CuraEngult和<代码> AppDebug < /Case>方法,而不是直接分配<代码> NoDEValue<代码>,但是我看不出如何在Tetro节点字符串的中间插入一个元素。

。为了做到这一点,必须使用DimString的接口。这接受一个偏移量,该偏移量可通过以下方式检索:


编辑:刚刚测试过,我意识到我没有删除第二个文本节点中的原始“临时”。编辑此答案就是为了做到这一点。我还对这段代码进行了编辑,使其与旧版本的PHP尽可能兼容:因为我没有运行旧版本的PHP,所以不可能对其进行测试。

使用修改过的元素创建一个新的DomDocument并替换旧的

 foreach ($elements as $element) {
   $text = $element->nodeValue;

   $el = new DomDocument();
   $el->loadHTML('<iframe>'. str_replace('interim','<span>interim</span>',$text) . '</iframe>');
   $new = $dom->importNode($el->getElementsByTagName('iframe')->item(0), true);
   unset($el);

   $element->parentNode->replaceChild($new, $element);
 }
foreach($elements作为$element){
$text=$element->nodeValue;
$el=新的DomDocument();
$el->loadHTML(“”.str_replace('middial','middial',$text)。“”);
$new=$dom->importNode($el->getElementsByTagName('iframe')->item(0),true);
未结算(el);
$element->parentNode->replaceChild($new,$element);
}

Marcus Harrison使用
splitText
的回答很好,但可以简化,需要使用mb_*方法来处理UTF-8输入:

<?php

$html = <<<END
<html>
<meta charset="utf-8">
<body>
    <div>
        <p>During € the interim there shall be nourishment supplied</p>
    </div>
</body>
</html>
END;

$replace = 'interim';

$doc = new DOMDocument;
$doc->loadHTML($html);

$xpath = new DOMXPath($doc);
$nodes = $xpath->query(sprintf('//text()[contains(., "%s")]', $replace));

foreach ($nodes as $node) { 
    $start = mb_strpos($node->textContent, $replace);
    $end = $start + mb_strlen($replace);

    $node->splitText($end); // do this first
    $node->splitText($start); // do this last

    $newnode = $doc->createElement('span');
    $node->parentNode->insertBefore($newnode, $node->nextSibling);
    $newnode->appendChild($newnode->nextSibling);
}

$doc->encoding = 'UTF-8';

print $doc->saveHTML($doc->documentElement);

这是总体思路。问题是“如何”请?
$text=$element->childNodes[0]
给出了一个错误:“致命错误:无法将DOMNodeList类型的对象用作数组”DOMNode的textContent属性也只能为PHP 5.6.1+编写,很遗憾我没有访问权限。很抱歉,在我使用的系统上,DOMNodeList上的数组语法起作用。在这种情况下,将
$element->childNodes[n]
的所有实例替换为
$element->childNodes->item(n)
。我将修改我的答案以反映这一点。我将研究如何修改DOMText对象的文本内容,但我相信这将涉及在空格字符之后执行另一次拆分,然后从树中删除最中间的DOMText。
<?php

$html = <<<END
<html>
<meta charset="utf-8">
<body>
    <div>
        <p>During € the interim there shall be nourishment supplied</p>
    </div>
</body>
</html>
END;

$replace = 'interim';

$doc = new DOMDocument;
$doc->loadHTML($html);

$xpath = new DOMXPath($doc);
$nodes = $xpath->query(sprintf('//text()[contains(., "%s")]', $replace));

foreach ($nodes as $node) { 
    $start = mb_strpos($node->textContent, $replace);
    $end = $start + mb_strlen($replace);

    $node->splitText($end); // do this first
    $node->splitText($start); // do this last

    $newnode = $doc->createElement('span');
    $node->parentNode->insertBefore($newnode, $node->nextSibling);
    $newnode->appendChild($newnode->nextSibling);
}

$doc->encoding = 'UTF-8';

print $doc->saveHTML($doc->documentElement);