PHP XPath如何在一个范围内包装p的内容

时间:2015-11-27 01:23:12

标签: php html xml xpath

我不知道你是否可以阅读JS Jquery,但这就是我想做的服务器支持而不是客户端支持:$('p').wrapInner('<span class="contentsInP" />');我想把所有现有的页面中的段落,并将其内容包装在具有特定类的新跨度中。

幸运的是,我的所有文档都是HTML5的XML风格,并且有效,因此在PHP中我可以这样做(简化):

$xml=new DOMDocument();
$xml->loadXML($html);
$xpath = new DOMXPath($xml);  
// How to go on in here to wrap my p's?
$output=$xml->saveXML();

如何让PHP的DOMXPath进行包装?

编辑:根据评论提出这个问题,但无法使其发挥作用

// based on http://stackoverflow.com/questions/8426391/wrap-all-images-with-a-div-using-domdocument    
$xml=new DOMDocument();
$xml->loadXML(utf8_encode($temp));
$xpath = new DOMXPath($xml);  
//Create new wrapper div
$new_span = $xml->createElement('span');
$new_span->setAttribute('class','contentsInP');
$ps = $xml->getElementsByTagName('p');
//Find all p
//Iterate though p
foreach ($ps AS $p) {
  //Clone our created span
  $new_span_clone = $new_span->cloneNode();
  //Replace p with this wrapper span
  $p->parentNode->replaceChild($new_span_clone,$p);
  //Append the p's contents to wrapper span
  // THIS IS THE PROBLEM RIGHT NOW:
  $new_span_clone->appendChild($p);
}
$temp=$xml->saveXML();

上面将p包裹在一个范围内,但我需要一个包裹p的内容的跨度,同时保持p在跨度...此外,如果p有一个类,则上面的失败,然后它赢了&#39感动。

1 个答案:

答案 0 :(得分:1)

在尝试调整其他答案时,需要改变的主要事情是获取<p>元素的所有子节点,首先将它们从<{em>中移除 1}}然后将他们作为子项添加到<p>。最后,将<span>附加为<span>

的子节点
<p>

给定输入HTML片段,这应该产生如下输出:(demonstration...

$html = <<<HTML
<!DOCTYPE html>
<html>
<head><title>xyz</title></head>
<body>
<div>
<p><a>inner 1</a></p>
<p><a>inner 2</a><div>stuff</div><div>more stuff</div></p>
</div>
</body>
</html>
HTML;

$xml=new DOMDocument();
$xml->loadXML(utf8_encode($html));

//Create new wrapper div
$new_span = $xml->createElement('span');
$new_span->setAttribute('class','contentsInP');
$ps = $xml->getElementsByTagName('p');
//Find all p
//Iterate though p
foreach ($ps AS $p) {
  //Clone our created span
  $new_span_clone = $new_span->cloneNode();

  // Get an array of child nodes from the <p>
  // (because the foreach won't work properly over a live nodelist)
  $children = array();
  foreach ($p->childNodes as $child) {
    $children[] = $child;
  }

  // Loop over that list of child nodes..
  foreach ($children as $child) {
    // Remove the child from the <p>
    $p->removeChild($child);
    // Append it to the span
    $new_span_clone->appendChild($child);
  }
  // Lastly, append the <span> as a child to the <p>
  $p->appendChild($new_span_clone);
}
$temp=$xml->saveXML();