Sandro99: Probleme beim Löschen von xml Einträgen in Playlist

Hallo Ihr,
irgenwie seh ich den Wald vor lauter Bäumen nicht mehr und wollt hier mal fragen ob mir der eine oder andere evtl. einen Hint geben kann was falsch läuft.

Ich habe eine playlist.xml welche dem namespace http://xspf.org/ns/0 unterliegt. Aus diesem File beabsichtige ich einzelne Einträge zu löschen. Das möchte ich über ein PHP script bewerkstelligen. Ich benutze dazu die DOM Funktionen.

Was bereits geht: wenn ich den NameSpace ausser betracht lasse (die zeile <playlist xmlns="http://xspf.org/ns/0/" version="1"> aus dem xml File entferne, funktioniert das Löschen prima. Mit diesem Eintrag jedoch nicht.

Soweit zur Vorgeschichte.

Hier das XML File gekürzt welches Verwendung findet.

  
<?xml version="1.0" encoding="UTF-8"?>  
<playlist xmlns="http://xspf.org/ns/0/" version="1">  
<trackList>  
	<track>  
	    <creator>Rico Seith</creator>  
            <title>Blumenmaedchen Nathalie</title>  
	    <location>/musik/Blumenmaedchen Nathalie - Rico Seith.mp3</location>  
	</track>  
	<track>  
	    <creator>Rico Seith</creator>  
            <title>Das geht auf einmal viel zu schnell</title>  
	    <location>/musik/Das geht auf einmal viel zu schnell - Rico Seith.mp3</location>  
	</track>  
	<track>  
	    <creator>Marcel</creator>  
            <title>Dieses Maedchen</title>  
	    <location>/musik/Dieses Maedchen - Marcel.mp3</location>  
	</track>  
    </trackList>  
</playlist>  

Hier das PHP Script welches ich verwenden möchte um Einträge zu löschen.

  
<?php  
  
$file = 'playlist.xml';  
$location = '/musik/Blumenmaedchen Nathalie - Rico Seith.mp3';  
  
$doc = new DOMDocument;  
$doc->load($file);  
$doc->preserveWhiteSpace = false;  
$doc->formatOutput = true;  
  
$xpath = new DOMXPath($doc);  
$xpath->registerNamespace('xspf', "http://xspf.org/ns/0");  
  
$nodeList = $xpath->query(sprintf('//xspf:track[location="%s"]', $location));  
$nodeList->item(0)->parentNode->removeChild($nodeList->item(0));  
  
$doc->save($file);  
  
?>  

Wie geschrieben, ohne den NameSpace im xml File sowie die Einträge mit dem registerNamespace und dem xspf: vor dem track in der nodeList funktioniert das Löschen.

Hat von Euch einer eine Idee oder im günstigsten Fall das Wissen wo es hier in meinen Überlegungen mangelt ?

Recht vielen Dank für dienliche Hinweise.
Gruss, Sandro

  1. Hi,

    Wie geschrieben, ohne den NameSpace im xml File sowie die Einträge mit dem registerNamespace und dem xspf: vor dem track in der nodeList funktioniert das Löschen.

    Und wie äußert sich das Gegenteil - also das „funzt nich“, dass du jetzt aber bitte *nicht* auf eben diese Weise beschreibst?

    MfG ChrisB

    --
    RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
    1. Hallo ChrisB,

      das ging aber flott, nach 10 Minuten, bin begeistert :)

      "Es funktioniert mit Namespace nicht" soll heisen das das playlist.xml unverändert bleibt jedoch auch keine Fehlermeldung angezeigt wird obwohl ich mit var_dump und error_reporting(E_ALL); versucht habe zu debugen. Google bemühe ich zu diesem Thema bereits seit meheren Stunden, leider erfolglos.

      Gruss, Sandro99

  2. Hi!

    Was bereits geht: wenn ich den NameSpace ausser betracht lasse (die zeile <playlist xmlns="http://xspf.org/ns/0/" version="1"> aus dem xml File entferne, funktioniert das Löschen prima. Mit diesem Eintrag jedoch nicht.

    Das Löschen funktioniert nicht, sagst du. Das heißt also, dass

    $nodeList = $xpath->query(sprintf('//xspf:track[location="%s"]', $location));
    $nodeList->item(0)->parentNode->removeChild($nodeList->item(0));

    in $nodeList->item(0)->parentNode der gewünschte Knoten steht und dass auch $nodeList->item(0) wie gewünscht befüllt ist. Wenn du das jedoch noch nicht geprüft hast, wäre das das erste, was man tun sollte, wenn eine davon abhängige Aktion nicht stattfindet.

    Wenn da schon nicht der gewünschte Wert steht, könnte das daran liegen, dass xspf:track gar kein Element location enthält. Ich sehe da auch keins in deinem Beispiel-XML. Und nein, ich bin zwar manchmal zu oberflächlich, aber in diesem Fall bin ich wirklich nicht blind. Außerdem ist ein Trailing Slash in einem URI von einiger Bedeutung.

    Lo!

    1. Hallo Lo,

      ja, ich sehe das eigentliche Problem in der fomatierung des xpath query. Mit dem Einsatz von Namespace bin ich eben nicht so vertraut. Auch viel goolgle'n hat an dieser Tasache nichts geändert.

      Track enthällt wohl ein Child location, denn ohne Namespace eintrag wird der correcte Node ja auch gelöscht, nur eben mit dem xspf nicht. Ich setze den wohl im query falsch ein.

      Hatte mich mal uaf die Suche nach Bespielen gemacht, ohne Erfolg.
      Hab mit // mit nur einen / und auch ganz ohne probiert. Es klappt in keinen der Faelle. Das Verständnis wie der query mit dem NS umgeht fehlt schlicht und ergreifend. Und ja, http://php.net/manual/de/domxpath.registernamespace.php habe ich mehrmals gelesen und wohl nicht grundlegend verstanden.

      Bin für Tips sehr dankbar aber bitte keine komplette Lösung, will ja lernen :)

      Danke
      Gruss, Sandro

      1. Hi!

        Track enthällt wohl ein Child location,

        Nein, es existiert kein track sondern ein xspf:track, und der enthält ein xspf:location. Alle Elemente unterhalb playlist befinden sich im Namespace. Voraussetzung ist allerdings, man registriert für das Alias xspf den selben Namespace wie im xmlns-Attribut und nicht zwei unterschiedliche.

        Lo!

  3. Hallo.

    nun hab ich doch noch einen Lösungsansatz im Netz gefunden.
    Diesen umgesetzt und nun scheint der xpath auch correct zu sein.

    Ich habe folgenden geänderten query jetzt eingesetzt:

      
    $xpath->registerNamespace('xspf', "http://xspf.org/ns/0/");  
    $nodeList = $xpath->query(sprintf('/xspf:playlist/xspf:trackList/xspf:track[xspf:location="%s"]', $location));  
    
    

    Danke Euch für die Tips.
    Gruss, Sandro

    1. Hi!

      $xpath->registerNamespace('xspf', "http://xspf.org/ns/0/");

      Ah, vergessenes / gefunden.

      $nodeList = $xpath->query(sprintf('/xspf:playlist/xspf:trackList/xspf:track[xspf:location="%s"]', $location));

      Etwas umständlich, //xspf:track[xspf:location] hätte es auch getan.

      Lo!