PHP SimpleXML - xpath düğümü Kaldır

4 Cevap php

Ben i bir XPath arama yoluyla bulabileceğiniz şey bir ana düğüm silebilirsiniz nasıl olarak biraz kafam karıştı:

$xml = simplexml_load_file($filename);
$data = $xml->xpath('//items/info[item_id="' . $item_id . '"]');
$parent = $data[0]->xpath("parent::*");
unset($parent);

Yani, madde id bulur, orada hiçbir sorun - ama unset bu <items> düğüm kurtulmak değildir. I yapmak istediğiniz tüm bu ürün için <items>...</items> kaldırmak olduğunu. Her şeyi silmek istiyorsunuz gibi unset($xml->data->items) yapamam yani Açıkçası, xml dosyasındaki <items> düğümler yükler vardır.

Çok takdir :-) Herhangi bir fikir

4 Cevap

<?php
$xml = new SimpleXMLElement('<a><b/></a>');
unset($xml->b);
echo $xml->asxml();

this works as intended (removing the <b/> element fromt he document) because the __unset() method (or the equivalent in the modules code) is called.
But when you call unset($parent); it only removes the object reference stored in $parent, but it doesn't affect the object itself or the document stored in $xml. I'd revert to DOMDocument for this.

<?php
$doc = new DOMDOcument;
$doc->loadxml('<foo>
  <items>
    <info>
      <item_id>123</item_id>
    </info>
  </items>
  <items>
    <info>
      <item_id>456</item_id>
    </info>
  </items>
  <items>
    <info>
      <item_id>789</item_id>
    </info>
  </items>
</foo>');
$item_id = 456;

$xpath = new DOMXpath($doc);
foreach($xpath->query('//items[info/item_id="' . $item_id . '"]') as $node) {
  $node->parentNode->removeChild($node);
}
echo $doc->savexml();

baskılar

<?xml version="1.0"?>
<foo>
  <items>
    <info>
      <item_id>123</item_id>
    </info>
  </items>

  <items>
    <info>
      <item_id>789</item_id>
    </info>
  </items>
</foo>

Bu benim için bu gibi çalışır. Başka unset($parent); fakat unset($parent[0]);,

$res    = $xml->xpath('//key/k[. = "string"]/parent::*');
$parent = $res[0];
unset($parent[0]);

Bu, self-reference to the simplexml-element in $parent (ya da $res[0]) oluşturarak çalışır.

Daha ayrıntılı bir açıklama için ilgili soruya Remove a child with a specific attribute, in SimpleXML for PHP a related answer bakın.

Ben kesinlikle bir filtreleme biri olarak bu sorunu yaklaşım olurdu - bir tane kaldırma değil.

Böylece, kopyalama Başka bir dizeye düğümleri gerekli veya bu konuda başka bir XML belgesi oluşturmak. Eğer bu tür senaryolar için kullanmak hangi araçları biliyorum.

Ben bu sorunu çözer değil sadece düşünüyorum, ama muhtemelen okumak ve anlamak için daha kolay tutar. Performans hit hakkında emin olmasa. Düzenli çalışmak kaç düğüm bize söyleyin.

Tek yönlü DOMDocument içine SimpleXML düğümü almak ve sonra DOMDocument içinde kaldırmaktır. Gerçekten yalındır, ama çalışıyor:

$xml = simplexml_load_file($filename);

$result = $xml->xpath("/cardsets/cardgroup");

foreach ($result as $el)
{
    if ($el['id'] == $id)
    {
        $domRef = dom_import_simplexml($el);
        $domRef->parentNode->removeChild($domRef);
        $dom = new DOMDocument('1.0');
        $dom->preserveWhiteSpace = false;
        $dom->formatOutput = true;
        $dom->loadXML($xml->asXML());
        $dom->save($filename);
        break;
    }
}