如何使用php删除基于子属性的XML标记?

时间:2016-10-12 15:18:00

标签: php xml xpath xml-parsing domdocument

我有一个类似下面的XML

<entries>
  <entry>
    <title lang="en">Sample</title>
    <entrydate>0</entrydate>
    <contents>0</contents>
    <entrynum>0</entrynum>
  </entry>
  <entry>
    <title lang="fr">Sample</title>
    <entrydate>1</entrydate>
    <contents>1</contents>
    <entrynum>1</entrynum>
  </entry>
</entries>

PHP中有没有办法根据标题entry属性删除父节点(lang)?我只需要保留en个,所以在这种情况下,我需要在没有第二个entry节点的情况下获取XML。

我试着环顾四周但找不到任何解决方案......

3 个答案:

答案 0 :(得分:1)

您需要使用DOMDocument类来解析字符串到XML文档。然后使用DOMXpath类在文档中查找目标元素,并使用DOMNode::removeChild()从文档中删除所选元素。

$doc = new DOMDocument(); 
$doc->loadXML($xml);
$xpath = new DOMXpath($doc);
// select target entry tag
$entry = $xpath->query("//entry[title[@lang='fr']]")->item(0);
// remove selected element
$entry->parentNode->removeChild($entry);
$xml = $doc->savexml();

您可以在demo

中查看结果

答案 1 :(得分:0)

您还可以阅读您的文件并使用您的修改生成新文件

<?php
$entries = array('title' => "What's For Dinner",
'link' => 'http://menu.example.com/',
'description' => 'Choose what to eat tonight.');
print "<entries>\n";
foreach ($entries as $element => $content) {
print " <$element>";
print htmlentities($content);
print "</$element>\n";
}
print "</entries>";
?>

答案 2 :(得分:0)

使用this回答中描述的方法,即

<?php
$xml = simplexml_load_file('1.xml');

$del_items = [];
foreach ($xml->entry as $e) {
  $attr = $e->title->attributes();
  if ($attr && $attr['lang'] != 'en') {
    $del_items []= $e;
  }
}

foreach ($del_items as $e) {
  $dom = dom_import_simplexml($e);
  $dom->parentNode->removeChild($dom);
}

echo $xml->asXML();

输出

<?xml version="1.0" encoding="UTF-8"?>
<entries>
  <entry>
    <title lang="en">Sample</title>
    <entrydate>0</entrydate>
    <contents>0</contents>
    <entrynum>0</entrynum>
  </entry>

</entries>

在第一个循环中无法删除项目,因为否则我们可能会破坏迭代链。相反,我们将条目对象收集到$del_items数组中,然后在单独的循环中将它们从XML中删除。