Thomas Mell: Namensraum ermitteln

Hallo,
gibt es eine Möglichkeit den Namensraum eines Elementes mit PHP festzustellen (getNamespace o.ä.) ?
Es existieren ja mehrere Möglichkeiten Namensräume zu definieren. In den folgenden Beispielen gehört das div-Element immer zum Namensraum "http://www.w3.org/1999/xhtml"
...
<title type="xhtml" xmlns:xhtml="http://www.w3.org/1999/xhtml">
  xhtml:div
    Less: xhtml:em &lt; </xhtml:em>
  </xhtml:div>
</title>
...
<summary type="xhtml">
   <div xmlns="http://www.w3.org/1999/xhtml">
      This is <b>XHTML</b> content.
   </div>
</summary>
...
<summary type="xhtml">
   <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml">
      This is xhtml:bXHTML</xhtml:b> content.
   </xhtml:div>
</summary>
...

<root xmlns:xh="http://www.w3.org/1999/xhtml">
.
.
<summary type="xhtml">
   xh:div
      This is xh:bXHTML</xh:b> content.
   </xh:div>
</summary>
...

Wie kann ich den Namensraum des div-Elementes in allen Fällen ermitteln (DOM, xPath oder wie auch immer) ?

Grüße
Thomas

  1. Hallo Thomas.

    Wie kann ich den Namensraum des div-Elementes in allen Fällen ermitteln (DOM, xPath oder wie auch immer) ?

    Vermutlich mit lookupPrefix.

    Einen schönen Montag noch.

    Gruß, Mathias

    --
    sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
    „It is required that HTML be a common language between all platforms. This implies no device-specific markup, or anything which requires control over fonts or colors, for example. This is in keeping with the SGML ideal.“
    [HTML Design Constraints: Logical Markup]
    1. Hallo,
      nein, funktioniert nicht ;-(((

      Grüße
      Thomas

      1. Hallo Thomas.

        nein, funktioniert nicht ;-(((

        Hm, sicher? Mein Versuch:

        $str_doc = '<?xml version="1.0" encoding="utf-8"?>  
        <title type="xhtml" xmlns:xhtml="http://www.w3.org/1999/xhtml">  
          <xhtml:div>  
            Less: <xhtml:em> &lt; </xhtml:em>  
          </xhtml:div>  
        </title>';  
          
        $obj_doc = new DOMDocument();  
        $obj_doc->loadXML($str_doc);  
          
        echo $obj_doc->getElementsByTagName('div')->item(0)->lookupPrefix('http://www.w3.org/1999/xhtml'); # → xhtml
        

        Einen schönen Montag noch.

        Gruß, Mathias

        --
        sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
        „It is required that HTML be a common language between all platforms. This implies no device-specific markup, or anything which requires control over fonts or colors, for example. This is in keeping with the SGML ideal.“
        [HTML Design Constraints: Logical Markup]
        1. Hallo nochmal.

          $str_doc = '<?xml version="1.0" encoding="utf-8"?>

          <title type="xhtml" xmlns:xhtml="http://www.w3.org/1999/xhtml">
            xhtml:div
              Less: xhtml:em &lt; </xhtml:em>
            </xhtml:div>
          </title>';

          $obj_doc = new DOMDocument();
          $obj_doc->loadXML($str_doc);

          echo $obj_doc->getElementsByTagName('div')->item(0)->lookupPrefix('http://www.w3.org/1999/xhtml'); # → xhtml

            
          Ich sehe gerade, dass die letzte Zeile noch etwas einfacher geht:  
            
          `echo $obj_doc->getElementsByTagName('div')->item(0)->[link:http://www.php.net/manual/en/ref.dom.php#dom.class.domnode.properties@title=prefix];`{:.language-php}  
            
          Dies entspricht eher dem, was du suchtest, oder Thomas?  
            
            
          Einen schönen Montag noch.  
            
          Gruß, Mathias  
          
          -- 
          sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|  
          „It is required that HTML be a common language between all platforms. This implies no device-specific markup, or anything which requires control over fonts or colors, for example. This is in keeping with the SGML ideal.“  
          [[HTML Design Constraints: Logical Markup](http://www.w3.org/History/19921103-hypertext/hypertext/WWW/MarkUp/HTMLConstraints.html)]
          
        2. Hallo,
          ich möchte nicht den Prefix (z. B. "xhtml") bekommen, sondern den Namensraum "http://www.w3.org/1999/xhtml".
          Der Prefix könnte auch fehlen:
          <summary type="xhtml">
             <div xmlns="http://www.w3.org/1999/xhtml">
                This is <b>XHTML</b> content.
             </div>
          </summary>

          ich habe da was mit XPath gefunden (namespace-uri), allerdings bekomme ich das nicht in PHP zum laufen:
          $XML = '
          <root xmlns:xh="http://www.w3.org/1999/xhtml" xmlns="http://abc.de">
          <summary type="xhtml">
             xh:div
                This is xh:bXHTML</xh:b> content.
             </xh:div>
          </summary>
          </root>';

          $dom = domxml_open_mem($XML);
          $xpath = $dom->xpath_new_context();

          $node = xpath_eval_expression($xpath, "namespace-uri(//root/summary/div)");

          Ich bekomme zwar ein Objekt geliefert, weiß aber nicht wie ich nun an den Namensraum kommen soll...

          Grüße
          Thomas

          1. Hallo Thomas.

            ich möchte nicht den Prefix (z. B. "xhtml") bekommen, sondern den Namensraum "http://www.w3.org/1999/xhtml".

            Dann nutzt du die namespaceURI–Eigenschaft des DOMNode–Objektes.

            $dom = domxml_open_mem($XML);
            $xpath = $dom->xpath_new_context();

            Ich sehe gerade, dass du von DOM XML sprichst, während ich mich auf das neue DOM beziehe. Steht dir letzteres auch zur Verfügung?

            Einen schönen Montag noch.

            Gruß, Mathias

            --
            sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
            „It is required that HTML be a common language between all platforms. This implies no device-specific markup, or anything which requires control over fonts or colors, for example. This is in keeping with the SGML ideal.“
            [HTML Design Constraints: Logical Markup]
          2. Hallo Thomas,

            ich habe da was mit XPath gefunden (namespace-uri), allerdings bekomme ich das nicht in PHP zum laufen:
            $xpath = $dom->xpath_new_context();
            $node = xpath_eval_expression($xpath, "namespace-uri(//root/summary/div)");

            Vielleicht klappt dieser XPath-Ausdruck besser:

            namespace-uri(/*:root/*:summary/*:div)

            In XPath-Ausdrücken kann man auch Namensräume verwenden. Allerdings nicht mit URI sondern mit Präfix. Sprich: "//atom:summary" wäre ein XPath-Ausdruck, der einem alle summary-Elemente aus Atoms Namensraum zurückgibt – vorausgesetzt das Präfix "atom" ist an die richtige URI gebunden. Für die Verwendung von XPath ausserhalb von XML, sprich in einer Programmiersprache muss man dann die von einem verwendeten Präfixe registrieren. Üblicherweise geschieht das mit einem Namensraum-Resolver, aber die Implementierung scheint dafür eine Funktion namens xpath_register_ns() vorzusehen. Ich hab nun den obigen XPath-Ausdruck mit Wildcards für die Namensräume verwendet, schließlich sind in Deinem Beispiel-XML root-, summary- und div-Elemente nicht im selben Namensraum. Ich kann mir schon vorstellen, dass dieses recht merkwürdige DOM XML von PHP 4 darüber ins Stolpern kommt.

            Zweiter Vorschlag: xpath_eval() kann – lese ich die „Dokumentation“ richtig – auch XPath-Ausdrücke auf einzelne Knoten ausführen. Ich würde dann dieses vorschlagen:

            xpath_eval($xpath_context, "namespace-uri(.)", $element);

            Als Argument habe ich in diesem XPath-Ausdruck nur den Punkt (".") übergeben, der in XPath soviel heisst, wie „aktueller Knoten“ – also hoffentlich derjenige, der durch das Argument $element bestimmt wird.

            Allerdings: Das ist alles ungetestet und reine Mutmassung; ich habe wenig Ahnung von PHP und noch weniger von dieser laut „Dokumentation“ extrem beknackten Variante des DOMs von PHP 4. Wenn Du meinen ungebeteten Rat als PHP-Unkundiger haben willst: Nimm die andere DOM-Implementierung, die sieht sehr viel vollständiger aus – vor allem hat sie das Attribut DOMNode.namespaceURI.

            Ansonsten fiele mir auch nichts ein, ausser selbst ein Namespace-Lookup mit den bestehenden von diesem DOM XML bereitgestellten Funktionen zu schreiben, sprich vom Element ausgehend immer weiter im Baum nach oben gehen und bei den jeweiligen Elternelement nach mit "xmlns" beginnenden Attributen Ausschau zu halten, sowohl in der Variante mit als auch ohne Präfixen.

            Tim

        3. im übrigen bekomme ich das hier geliefert:
          Parse error: parse error, unexpected T_OBJECT_OPERATOR, expecting ',' or ';' in g:\server\test.php on line 27
          Das betrifft die letzte Zeile.

          Kann es sein das die Sache nur in PHP 5 läuft? Ich muß mit PHP 4 klarkommen...

          1. Hallo Thomas.

            im übrigen bekomme ich das hier geliefert:
            Parse error: parse error, unexpected T_OBJECT_OPERATOR, expecting ',' or ';' in g:\server\test.php on line 27
            Das betrifft die letzte Zeile.

            Kann es sein das die Sache nur in PHP 5 läuft? Ich muß mit PHP 4 klarkommen...

            OK, dann erübrigt sich meine Frage.

            Beim DOM XML kann ich dir nicht helfen, da ich mich damit nicht auskenne. Aber so wie es aussieht, kann man hier mit den DOM–eigenen Methoden lediglich den Präfix erfahren. Ob und wie man an die zugehörige URI kommen kann, weiß ich leider nicht.

            Einen schönen Montag noch.

            Gruß, Mathias

            --
            sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
            „It is required that HTML be a common language between all platforms. This implies no device-specific markup, or anything which requires control over fonts or colors, for example. This is in keeping with the SGML ideal.“
            [HTML Design Constraints: Logical Markup]