我正在尝试对HTML中的文本执行preg_replace。我希望避免替换标记中的文本,因此我将字符串作为DOM元素加载,并获取每个节点中的文本。例如,我有这个列表:
<ul>
<li><a href="?p=oconnorinv&i=1">Boxes 1-3</a>: 1925 - 1928 <em>(A-Ma)</em></li>
<li><a href="?p=oconnorinv&i=2">Boxes 4-6</a>: 1928 <em>(Mb-Z)</em> - 1930 <em>(A-Wi)</em></li>
<li><a href="?p=oconnorinv&i=3">Boxes 7-9</a>: 1930 <em>(Wo-Z)</em>- 1932 <em>(A-Fl)</em></li>
</ul>我希望能够突出显示字符"1“或字母"i",而不干扰链接或列表项标记。所以我抓取每个列表项并获取它的值来执行替换:
$invfile = [string of the unordered list above]
$invcontents = new DOMDocument;
$invcontents->loadHTML($invfile);
$inv_listitems = $invcontents->getElementsByTagName('li');
foreach ($inv_listitems as $f) {
$f->nodeValue = preg_replace($to_highlight, "<span class=\"highlight\">$0</span>", $f->nodeValue);
}
echo html_entity_decode($invcontents->saveHTML());问题是,当我获取节点值时,列表项中的子节点会丢失。如果按原样打印原始字符串,、< em >等标记都在那里。但当我运行该脚本时,它打印出的内容没有链接或任何格式化标记。例如,如果我的$to_replace是字符串"Boxes",则列表变为:
<ul>
<li><span class="highlight">Boxes</span> 1-3: 1925 - 1928 (A-Ma)</li>
<li><span class="highlight">Boxes</span> 4-6: 1928 (Mb-Z) - 1930 (A-Wi)</li>
<li><span class="highlight">Boxes</span> 7-9: 1930 (Wo-Z)- 1932 (A-Fl)</li>
</ul>怎样才能在不丢失标签的情况下获得文本?
发布于 2011-03-15 02:41:04
这里的问题是,你是在整个
如果上面的结构总是相同的,你可以这样做
$new_html = preg_replace("##","",$f->item(0)->nodeValue);
实际上,最好的方法是取消设置锚点的节点值,创建一个全新的元素并追加它。
(考虑下面的psuedo代码)
$inv_listitems = $invcontents->getElementsByTagName('li');foreach ($inv_listitems as $f) { $span = $invcontents->createElement("span");$span->setAttribute("class","highlight");$span->nodeValue = $f->item(0)->nodeValue;$f->appendChild($span);} echo $invcontents>saveHTML();
你必须在那里做一些匹配,以及取消设置$f的nodeValue,但希望这能让它更清楚一些。
另外,不要在nodeValue中直接设置HTML,因为它会对您设置的所有html运行htmlentities()。这就是我在上面创建一个新元素的原因。如果一定要在nodeValue中设置超文本标记语言,那么应该创建一个DocumentFragment Object
发布于 2011-03-15 03:32:04
你最好只在文本节点上操作:
$x = new DOMXPath(invcontents);
foreach($x->query('//li/text()' as $textnode){
//replace text node with list of plain text nodes & your highlighting span.
}发布于 2013-02-22 14:03:46
对于这类操作,我总是使用xpath。它会给你更多的灵活性。此示例处理
<mainlevel>
<toplevel>
<detaillevel key=...>
<xmlvalue1></xmlvalue1>
<xmlvalue1></xmlvalue2>
<sublevel key=...>
<xmlvalue1></xmlsubvalue1>
<xmlvalue1></xmlsubvalue2>
</sublevel>
</detaillevel>
</toplevel>
</mainlevel>要解析它,请执行以下操作:
$xpath = new DOMXPath($xmlDoc);
$mainNodes = $xpath->query("/mainlevel/toplevel/detaillevel");
foreach( $mainNodes as $subNode ) {
$parameter1=$subNode->getAttribute('key');
$parameter2=$subNode->getElementsByTagName("xmlvalue1")->item(0)->nodeValue;
$parameter3=$subNode->getElementsByTagName("xmlvalue2")->item(0)->nodeValue;
foreach ($subNode->getElementsByTagName("sublevel") as $detailNode) {
$parameter1=$detailNode->getAttribute('key');
$parameter2=$detailNode->getAttribute('xmlsubvalue1');
$parameter2=$detailNode->getAttribute('xmlsubvalue2');
}
}https://stackoverflow.com/questions/5302653
复制相似问题