按子元素的值删除XML元素

时间:2016-10-05 15:31:02

标签: php xml openxml domdocument domparser

我有一个xml文件,如:

<file>
    <data>
        <input name="id">1</input>
        <input name="name">Mike</input>
    </data>
    <data>
        <input name="id">2</input>
        <input name="name">Andree</input>
    </data>
</file>

如何element:data

删除值element:input 1 中的attribute:id

我已经阅读了这个例子php-delete-xml-element,但这与我正在寻找的深度不同。

NB:我希望使用DOMDocument

2 个答案:

答案 0 :(得分:2)

使用 DOMDocument 实现此目的的方法,类似于sevavietl发布的非常好的示例,是做同样的事情并使用XPath找到我们的节点。

DOMNode类有一个removeChild方法,我们的元素扩展为DOMElement。为了删除节点,我们需要使用包含我们想要删除的节点的父元素。在所有DOMNode上,我们有一个名为parentNode的属性,如果没有父级,则此属性将始终返回父级或null(当您到达documentElement节点或者您创建了一个节点而未插入它时例如)。

// Load the dom document
$document = new DOMDocument();
$document->load('./path/to/xml.xml'); 
// use $document->loadXML($xml) if you're passing a XML string

// Create XPath for the document
$xpath = new DOMXpath($document);

// Use XPath to locate our node(s)
$nodelist = $xpath->query('.//input[@name="id"][contains(., '1')]/..', $document->documentElement);

// Iterate over our node list and remove the data
foreach ($nodelist as $dataNode) {
    if ($dataNode->parentNode === null) {
        continue; // Uh oh, no parent node?
    }
    // Get the data node parent (file) so we can call remove child
    $dataNode->parentNode->removeChild($dataNode);
}

所有真正的魔力都在我们的XPath中:

    来自上下文节点的
  • .//input,找到任意深度的输入元素
  • [@name="id"]我们要查找的节点必须具有id
  • 的name属性
  • [contains(.,'1')]该节点必须包含文本1
  • /..从我们找到的节点向上移动一层

上下文节点始终是传递给XPath的query方法的第二个参数。因此,如果我们将它们放在一起,我们将得到XPath语句,找到名称属性等于id且包含文本1的所有输入节点。从那里将DOM树向上移动一级。

例如,如果您的DOM树包含其他元素,其中包含具有相同属性的input元素,并且我们只想删除data元素,我们可以将查询更改为

.//data/input[@name="id"][contains(., '1')]/..

现在,这意味着查找具有input直接祖先的所有data个节点。然后像以前一样应用我们的其他条件。

答案 1 :(得分:1)

我知道您希望使用 DOMDocument 执行此操作,但如果您只是需要删除节点,则可以使用SimpleXmlElementXPath执行此操作:

$xml = new SimpleXMLElement($xmlString);

$id = 1;

$data = $xml->xpath('//input[@name="id"][.=' . $id . ']/..');

if (isset($data[0])) {
    unset($data[0]->{0});
}

Here is working demo.

解释了unset()的魔力here