Thomas Mell: Problem mit PHP5 und xpath

Hallo,
ich habe folgendes Problem mit PHP5:

<?  
$xml = '<?xml version="1.0" encoding="utf-8"?>  
<root>  
  <x:test xmlns:x="http://foo"/>  
</root>';  
  
$dom = new DOMDocument;  
$dom->loadXML($xml);  
$xpath = new DOMXPath($dom);  
echo $xpath->query("/root/x:test")->length;  
?>

Das wirft nen Fehler "Undefined namespace prefix in...."
Dagegen funktioniert das hier einwandfei:

<?  
$xml = '<?xml version="1.0" encoding="utf-8"?>  
<x:root xmlns:x="http://foo">  
  <test/>  
</x:root>';  
  
$dom = new DOMDocument;  
$dom->loadXML($xml);  
$xpath = new DOMXPath($dom);  
echo $xpath->query("/x:root/test")->length;  
?>

Hat jemand eine Idee woran das liegen kann ?

Grüße
Thomas

  1. Hellihello

    Hat jemand eine Idee woran das liegen kann ?

    Vielleicht an dem "Undefined namespace prefix in..."?

    Dank und Gruß,

    frankx

    --
    tryin to multitain  - Globus = Planet != Welt
    1. Hi,

      Vielleicht an dem "Undefined namespace prefix in..."?

      Der Prefix ist aber im XML definiert...

      Grüße
      Thomas

      1. Hellihello

        Hi,

        Vielleicht an dem "Undefined namespace prefix in..."?
        Der Prefix ist aber im XML definiert...

        Du hast Recht. Der Fehler tauch ja auch bei der XPath-query auf.

        Dank und Gruß,

        frankx

        --
        tryin to multitain  - Globus = Planet != Welt
        1. Hellihello

            
          <root xmlns:x="http://foo">  
            <x:test>asdadsf</x:test>  
          </root>  
          
          

          So geht die Deklaration scheinbar.

          s.u.a.a. http://www.w3.org/TR/REC-xml-names/

          Dank und Gruß,

          frankx

          --
          tryin to multitain  - Globus = Planet != Welt
  2. Moin,

    $dom = new DOMDocument;
    $dom->loadXML($xml);
    $xpath = new DOMXPath($dom);
    echo $xpath->query("/root/x:test")->length;
    ?>[/code]

    Du musst den Namespace explizit registrieren.

    Gruß

    Stareagle

    1. Hi,

      Du musst den Namespace explizit registrieren.

      Warum? In dem anderen Beispiel muß man es nicht.

      Grüße
      Thomas

      1. Hallo,

        Hi,

        Du musst den Namespace explizit registrieren.
        Warum? In dem anderen Beispiel muß man es nicht.

        in deinem zweiten Bespiel ist der Namespace mit dem Prefix "X" der Default-Namespace des Dokuments (da er im Root-Element definiert wurde).

        Gruß

        Stareagle

        1. Hi,

          in deinem zweiten Bespiel ist der Namespace mit dem Prefix "X" der Default-Namespace des Dokuments (da er im Root-Element definiert wurde).

          Richtig, und?
          Im ersten Beispiel gehört das Element "test" dem Namensraum ="http://foo" mit dem Prefix "x" an. Demnach sollte es mit /root/x:test anzusprechen sein.
          Folgendes funktioniert auch wunderbar:

          <?  
          $xml = '<?xml version="1.0" encoding="utf-8"?>  
          <root xmlns:x="http://foo">  
            <x:test/>  
          </root>';  
            
          $dom = new DOMDocument;  
          $dom->loadXML($xml);  
          $xpath = new DOMXPath($dom);  
          echo $xpath->query("/root/x:test")->length;  
          ?>
          

          So wie es aussieht verarbeitet PHP nur solche Namensräume, welche im root-Element definiert werden. So weit mir bekannt ist, darf man das aber in allen Elementen, zumindest habe ich in den W3C-Specs nichts Gegenteiliges gefunden, lasse mich aber gerne eines Besseren belehren.

          Grüße
          Thomas

          1. So wie es aussieht verarbeitet PHP nur solche Namensräume, welche im root-Element definiert werden. So weit mir bekannt ist, darf man das aber in allen Elementen, zumindest habe ich in den W3C-Specs nichts Gegenteiliges gefunden, lasse mich aber gerne eines Besseren belehren.

            Hmm, kann gut sein. Die Ursache für das Verhalten ist aber nicht PHP sondern die libxml2, auf die PHP zurückgreift. Ich benutze die libxml2 derzeit in einem in C geschriebenen Projekt, und dort muss man es genauso machen.

            Das gleiche gilt auch für die im Java SDK enthaltenen Klassen für XPath, wenn ich mich nicht sehr irre.

            Gruß

            Stareagle

  3. Hallo Thomas,

    <?

    $xml = '<?xml version="1.0" encoding="utf-8"?>
    <root>
      <x:test xmlns:x="http://foo"/>
    </root>';

    $dom = new DOMDocument;
    $dom->loadXML($xml);
    $xpath = new DOMXPath($dom);
    echo $xpath->query("/root/x:test")->length;
    ?>

      
    Probier mal:  
      
    ~~~php
    $xpath = new DOMXPath($dom);  
    $xpath->registerNamespace ('x', 'http://foo');  
    echo $xpath->query("/root/x:test")->length;
    

    Funktionieren würde z.B. auch:

    $xpath = new DOMXPath($dom);  
    $xpath->registerNamespace ('bla', 'http://foo');  
    echo $xpath->query("/root/bla:test")->length;
    

    Viele Grüße,
    Christian