2009-07-20 13 views
5

Potrzebuję usunąć elementy pliku XML przy użyciu PHP. Zostanie to zrobione przez ajax i muszę znaleźć element XML za pomocą atrybutu.PHP - Usuń element XML

To jest mój plik XML

<?xml version="1.0" encoding="utf-8"?> 
<messages> 
    <message time="1248083538"> 
     <name>Ben</name> 
     <email>Ben's Email</email> 
     <msg>Bens message</msg> 
    </message> 
    <message time="1248083838"> 
     <name>John Smith</name> 
     <email>[email protected]</email> 
     <msg>Can you do this for me?</msg> 
    </message> 
</messages> 

Więc co chciałbym powiedzieć, to coś jak usunąć element, gdzie czas jest równy 1248083838.

Ive XML za pomocą prostych aż do teraz i mam tylko zdał sobie sprawę, że może zrobić wszystko oprócz elementów usuwania.

Jak to zrobić?

Odpowiedz

7

Możesz używać klas DOM w PHP. (http://us3.php.net/manual/en/intro.dom.php).

Będziesz musiał przeczytać dokument XML w pamięci, użyć klas DOM do manipulacji, a następnie zapisać XML w razie potrzeby (do http lub do pliku).

DOMNode to obiekt, który usunął funkcje (aby odpowiedzieć na twoje pytanie).

To trochę bardziej skomplikowane niż SimpleXML ale kiedy już do niego przyzwyczaić, jest dużo bardziej wydajne

(semi-zaczerpnięty z przykładu kodu na php.net)

<?php 

$doc = new DOMDocument; 
$doc->load('theFile.xml'); 

$thedocument = $doc->documentElement; 

//this gives you a list of the messages 
$list = $thedocument->getElementsByTagName('message'); 

//figure out which ones you want -- assign it to a variable (ie: $nodeToRemove) 
$nodeToRemove = null; 
foreach ($list as $domElement){ 
    $attrValue = $domElement->getAttribute('time'); 
    if ($attrValue == 'VALUEYOUCAREABOUT') { 
    $nodeToRemove = $domElement; //will only remember last one- but this is just an example :) 
    } 
} 

//Now remove it. 
if ($nodeToRemove != null) 
$thedocument->removeChild($nodeToRemove); 

echo $doc->saveXML(); 
?> 

To powinno dać masz trochę pomysłu na usunięcie elementu. To wydrukuje XML bez tego węzła. Jeśli chcesz wysłać go do pliku, po prostu napisz ciąg do pliku.

+0

Hmm ... Jestem trochę przytłoczony tym wszystkim. Czy możesz wyjaśnić nieco więcej? –

+0

Pewnie. Będę edytować. –

+0

Nie miałem szansy sprawdzić drobnych błędów składni - ale to powinno dać ci coś, czego potrzebujesz. Zalecam, aby nie usuwać potomka z samego forloopu, ponieważ jest ono zakłócane przez wewnętrzny licznik foreach. –

9

Dave Morgan ma rację, że zajęcia DOM są bardziej skuteczne, ale w przypadku, gdy chcesz, aby trzymać z SimpleXML, spróbuj użyć funkcji unset() na każdym węźle. Na przykład. unset ($ simpleXMLDoc-> node1-> child1), który zostanie usunięty z pliku XML.

+0

Nie próbowałem tego robić, ale logika podpowiada, że ​​powinna działać dobrze. Brzmi jak szybkie, brudne, ale właściwe dzieło dookoła mnie. –

+3

Nie brzmi dla mnie szybko-n-brudno. Brzmi jak normalne kodowanie. – Tjorriemorrie

1

Nawet SimpleXML nie posiada szczegółowy sposób, aby usunąć elementy, można usunąć elementy z SimpleXML za pomocą PHP unset(). Kluczem do tego jest dążenie do pożądanego elementu. Przynajmniej jednym ze sposobów na kierowanie jest użycie kolejności elementów. Najpierw dowiedzieć się numer porządkowy elementu, który chcesz usunąć (na przykład za pomocą pętli), a następnie usunąć element:

$target = false; 
$i = 0; 
foreach ($xml->message as $m) { 
    if ($m['time']=='1248083838') { $target = $i; break; } 
    $i++; 
} 
if ($target !== false) { 
    unset($xml->message[$target]); 
} 

Można nawet usunąć wiele elementów z tym, przechowując numer zamówienia elementów docelowych w tablicy. Po prostu pamiętaj, aby wykonać usuwanie w odwrotnej kolejności (array_reverse($targets)), ponieważ usunięcie elementu w naturalny sposób zmniejsza numer porządkowy elementów, które nadejdą po nim.

Wprawdzie jest to trochę hackaround, ale wygląda na to, że działa dobrze.