删除父节点,使用PHP将所有子元素保留在嵌套XML中

时间:2017-03-02 09:07:35

标签: php xml domdocument

我有嵌套XML,我只想删除父节点<项>在xml文档中保留其所有子节点。

<root>
  <items>
    <Product>
       <name> </name>
       <size> </size>
       <images>
          <img1></img1>
          <img2></img2>  
       </images>
    </Product>
    <Product>
       <name> </name>
       <size> </size>
       <images>
          <img1></img1>
          <img2></img2>  
       </images>
    </Product>  
  </items>
</root> 

预期产出 -

<root>
    <Product>
       <name> </name>
       <size> </size>
       <images>
          <img1></img1>
          <img2></img2>  
       </images>
    </Product>
    <Product>
       <name> </name>
       <size> </size>
       <images>
          <img1></img1>
          <img2></img2>  
       </images>
    </Product>  
</root>  

我研究过&amp;在尝试删除&lt;项&GT;节点的所有子节点也被删除。如果有任何方式在php中使用DOMDocument或任何其他方式,请提供帮助。

2 个答案:

答案 0 :(得分:0)

正如@ThW所提到的,你必须收集ITEMS中的子节点,然后将它们插入ROOT,最后删除ITEMS。

$input = "
<root>
 <items>
  <Product>
   <name> </name>
   <size> </size>
   <images>
    <img1></img1>
    <img2></img2>  
   </images>
  </Product>
  <Product>
   <name> </name>
   <size> </size>
   <images>
    <img1></img1>
    <img2></img2>  
   </images>
  </Product>
 </items>
</root>";

$doc = new DOMDocument();
$ret = $doc->loadXML($input);
$root = $doc->firstChild;
$nodes_to_insert = array();
$nodes_to_remove = array();
foreach($root->childNodes as $items) {
    if($items->nodeName != "items") {
        continue;
    }
    $nodes_to_remove[] = $items;
    foreach($items->childNodes as $child) {
        if($child->nodeType != XML_ELEMENT_NODE) {
            continue;
        }
        $nodes_to_insert[] = $child;
    }
}
foreach($nodes_to_insert as $node) {
    $root->appendChild($node);
}
foreach($nodes_to_remove as $node) {
    $root->removeChild($node);
}
var_dump($doc->saveXML());

此代码将搜索root中的所有“items”标记,而不仅仅是一个。在“items”中,它将搜索所有正常节点(ELEMENT类型,但没有TEXT节点等) 在最后一行有一个转储,但由于XML标题行,通常你不会在浏览器中看到任何内容。但是,如果您查看页面源,将显示结果。

PS:走路时不要修改xml结构是非常重要的。这就是我首先只进行收集,然后进行插入和删除操作的原因。

答案 1 :(得分:0)

那么,Geza Boems的回答并不完全是我的意思。使用Xpath,您可以获取items个节点进行迭代。这是一个稳定的结果,因此您可以在修改DOM时进行迭代。

$document = new DOMDocument();
$document->loadXML($input);
$xpath = new DOMXpath($document);

foreach ($xpath->evaluate('//items') as $itemsNode) {
  // as long that here is any child inside it
  while ($itemsNode->firstChild instanceof DOMNode) {
    // move it before its parent
    $itemsNode->parentNode->insertBefore($itemsNode->firstChild, $itemsNode);
  }
  // remove the empty items node
  $itemsNode->parentNode->removeChild($itemsNode);
}
echo $document->saveXML();