2015-09-29 2 views
3

Мне нужно добавить дочерние элементы к родительским узлам, но родительский узел должен быть div.Как добавить дочерний элемент в родительский узел div?

Мне нужно проверить, если родительский узел не div, тогда проверьте родительский узел родителя, пока я не получу div-узел. Как это сделать?

XML файл

<div class="parent"> 
     <div class="boxed-text">box text1</div> 
     <li> 
     <div class="boxed-text">box text2</div> 
     <p>para</p> 
     </li> 
     <div class="boxed-text">box text3</div> 
     <p>para</p> 
    </div> 

Ожидаемый результат (должен приложить к ДИВЫМ родительскому узлу)

<div class="parent"> 
     <li> 
     <p>para</p> 
     </li>  
     <p>para</p> 
     <div class="boxed-text">box text1</div> 
     <div class="boxed-text">box text2</div> 
     <div class="boxed-text">box text3</div> 
    </div> 

Но у меня есть выход, как показано ниже: (т.е. родительского узел в штучной упаковке -text 2 является тегом li, поэтому он добавляется там вместо родительского узла div. Как получить только родительский узел div для добавления дочерних узлов?)

<div class="parent"> 
     <li> 
     <p>para</p> 
     <div class="boxed-text">box text2</div> 
     </li>  
     <p>para</p> 
     <div class="boxed-text">box text1</div> 
     <div class="boxed-text">box text3</div> 
    </div> 

мой код:

$dom = new DOMDocument; 
$dom->load("new_test.xml", LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); 
$xp = new DOMXPath($dom); 
$xp->registerNamespace("php", "http://php.net/xpath"); 
$div = $xp->query("//div[@class='boxed-text']"); 
foreach($div as $divv) { 
    $divv->parentNode->appendChild($divv); 
    } 
$r = $dom->saveXML(); 

ответ

1

добавляемого узел в их родительском узел, но это будет просто переместить их в последнюю позицию внутри parent - он не изменит родителя.

Xpath имеет концепцию осей. Ось по умолчанию: child - дети текущего контекста. Но здесь несколько других, включая ancestor, который представляет путь к корню документа.

$dom = new DOMDocument; 
$dom->preserveWhiteSpace = false; 
$dom->formatOutput = true; 
$dom->load("new_test.xml", LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); 
$xp = new DOMXPath($dom); 
$xp->registerNamespace("php", "http://php.net/xpath"); 

$divs = $xp->evaluate("//div[@class='boxed-text']"); 
foreach($divs as $div) { 
    $ancestor = $xp->evaluate('ancestor::div[1]', $div)->item(0); 
    if ($ancestor) { 
    $ancestor->appendChild($div); 
    } 
} 

echo $dom->saveXML(); 

Выход:

<?xml version="1.0"?> 
<div class="parent"> 
    <li> 
    <p>para</p> 
    </li> 
    <p>para</p> 
    <div class="boxed-text">box text1</div> 
    <div class="boxed-text">box text2</div> 
    <div class="boxed-text">box text3</div> 
</div> 

Другим способом будет пересекать элементы Div родительских и получить коробочные полнотекстовые потомок для каждого из них:

$parents = $xp->evaluate("//div[.//div[@class='boxed-text']]"); 
foreach ($parents as $parent) { 
    foreach ($xp->evaluate(".//div[@class='boxed-text']", $parent) as $text) { 
    $parent->appendChild($text); 
    } 
} 
+0

Отлично! Огромное спасибо. Я попробовал второй способ, он работает. – Learning

0

Приведенный ниже код не проверял, но я хотел бы использовать XPath для получения родительского узла явно, а не с помощью метода ParentNode вы в настоящее время и удалить элементы DIV от йот в первом цикле, а затем добавить их обратно в конце

$tmp=array(); 
$dom = new DOMDocument; 
$dom->load("new_test.xml", LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); 

$xp = new DOMXPath($dom); 
$xp->registerNamespace("php", "http://php.net/xpath"); 

/* Find the parent based on it's class */ 
$parent=$xp->query("//div[class='parent']")->item(0); 

/* Find the nodes of interest and remove - store in temp array */ 
$col = $xp->query("//div[@class='boxed-text']"); 
foreach($col as $node) $tmp[]=$parent->removeChild($node); 

/* Add the nodes back at the end */ 
foreach($tmp as $node) $parent->appendChild($node); 

$r = $dom->saveXML(); 
+0

На самом деле, 'DIV класс = «parent» - просто пример, класс будет тем, что не определено заранее. – Learning

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