wahsaga: SimpleXML: einzelner Kindknoten vs. Array von Kindknoten

hi,

wenn ich ein XML-Dokument mittels SimpleXML einlese, erhalte ich an der Stelle, wo ein Element nur einen Kindknoten eines bestimmten Typs (also NodeNames) hat, ein weiteres SimpleXMLElement als Repräsentation dieses Kindknotens [1] - hat das Element jedoch mehrere Kindknoten dieses Typs, erhalte ich ein Array von SimpleXMLElementen [2].

Lässt sich dieses Verhalten beeinflussen, so dass ich auch wenn nur ein Kindknoten eines NodeNames vorhanden ist, ein Array mit entsprechend nur einem Eintrag erhalte [3]?

Es würde die Verarbeitung für mein Vorhaben nämlich vereinfachen, wenn ich immer gleich mittels foreach() über die oder den Kindknoten iterieren könnte - ohne zunächst abprüfen zu müssen, ob ich nun ein Array aus Kindknoten oder nur einen einzigen Kindknoten vorliegen habe.

Seit PHP 5.1.0 und libxml 2.6.0 können zwar vordefinierte libxml-Konstanten als options bei der Erzeugung eines SimpleXMLElements angegeben werden - aber da entdecke ich keine, die das gewünschte Verhalten bewirken würde.

Haben die PHP-Entwickler an eine solche Möglichkeit tatsächlich nicht gedacht - oder habe ich sie lediglich übersehen/nicht erkannt?

[1] Ausgabe print_r() für dieses Szenario:

SimpleXMLElement Object  
(  
    [parentElement] => SimpleXMLElement Object  
        (  
            [childNode] => SimpleXMLElement Object  
                (  
                    [contentNode] => Inhalt Child 1  
                )  
  
        )  
  
)

[2] Ausgabe print_r() für dieses Szenario:

SimpleXMLElement Object  
(  
    [parentElement] => SimpleXMLElement Object  
        (  
            [childNode] => Array  
                (  
                    [0] => SimpleXMLElement Object  
                        (  
                            [contentNode] => Inhalt Child 1  
                        )  
  
                    [1] => SimpleXMLElement Object  
                        (  
                            [contentNode] => Inhalt Child 2  
                        )  
  
                )  
  
        )  
  
)

[3] Ausgabe des gewünschten Ergebnisses mit print_r() für dieses Szenario:

SimpleXMLElement Object  
(  
    [parentElement] => SimpleXMLElement Object  
        (  
            [childNode] => Array  
                (  
                    [0] => SimpleXMLElement Object  
                        (  
                            [contentNode] => Inhalt Child 1  
                        )  
  
                )  
  
        )  
  
)

gruß,
wahsaga

--
/voodoo.css:
#GeorgeWBush { position:absolute; bottom:-6ft; }
  1. hi wahsaga,

    Du denkst viel zu kompliziert. SimpleXML arbeitet nicht mit richtigen Arrays, sondern mit Pseudo-Arrays. Betrachte folgenden Beispielcode:

    <?php  
      
    $xml = '<test><foo>bla</foo></test>';  
      
    $sxml = simplexml_load_string ($xml);  
      
    foreach ($sxml->foo as $foo) {  
      var_dump ((string)$foo);  
    }  
      
    $xml = '<test><foo>gugug</foo><foo>blub</foo></test>';  
      
    $sxml = simplexml_load_string ($xml);  
      
    foreach ($sxml->foo as $foo) {  
      var_dump ((string)$foo);  
    }  
      
    ?>
    

    Der liefert folgende Ausgabe:

    christian@cobalt ~/tmp $ php simplexml-test.php
    string(3) "bla"
    string(5) "gugug"
    string(4) "blub"

    Du kannst $sxml->knoten_name also immer mit foreach durchlaufen, egal, ob nur ein Knoten existiert, oder mehrere.

    Viele Grüße,
    Christian

    --
    "I have always wished for my computer to be as easy to use as my telephone; my wish has come true because I can no longer figure out how to use my telephone." - Bjarne Stroustrup
    1. hi,

      Du denkst viel zu kompliziert. SimpleXML arbeitet nicht mit richtigen Arrays, sondern mit Pseudo-Arrays. [...]
      Du kannst $sxml->knoten_name also immer mit foreach durchlaufen, egal, ob nur ein Knoten existiert, oder mehrere.

      Vielen Dank, der Hinweis fehlte mir.

      Das Manual drückt es nicht gerade ersichtlich aus:
      "When multiple instances of an element exist as children of a single parent element, normal iteration techniques apply."
      OK, aber das foreach dann auch geht, wenn es nur eine "single" statt "multiple instances" gibt, muss man ja erst mal wissen :-)

      gruß,
      wahsaga

      --
      /voodoo.css:
      #GeorgeWBush { position:absolute; bottom:-6ft; }
      1. Hallo wahsaga,

        OK, aber das foreach dann auch geht, wenn es nur eine "single" statt "multiple instances" gibt, muss man ja erst mal wissen :-)

        Ausprobieren? ;-) Ich wußte das vor meinem Posting auch nicht, ich hab's einfach probiert. Gerade bei einigen Klassen, die in PHP5 dazugekommen sind bzw. reimplementiert wurden (ich denke da vor allem an die Windows-COM-Implementierung) geht foreach() jetzt auch bei anderen Dingen als Arrays.

        Viele Grüße,
        Christian

        --
        "I have always wished for my computer to be as easy to use as my telephone; my wish has come true because I can no longer figure out how to use my telephone." - Bjarne Stroustrup
        1. hi,

          Ausprobieren? ;-)

          Schien mir zu abwegig - foreach reagiert doch sonst allergisch, wenn's kein Array zu essen bekommt.

          Ich wußte das vor meinem Posting auch nicht, ich hab's einfach probiert. Gerade bei einigen Klassen, die in PHP5 dazugekommen sind bzw. reimplementiert wurden (ich denke da vor allem an die Windows-COM-Implementierung) geht foreach() jetzt auch bei anderen Dingen als Arrays.

          Gut zu wissen, Danke.

          gruß,
          wahsaga

          --
          /voodoo.css:
          #GeorgeWBush { position:absolute; bottom:-6ft; }
          1. echo $begrüßung;

            Schien mir zu abwegig - foreach reagiert doch sonst allergisch, wenn's kein Array zu essen bekommt.

            Ja, aber die SPL macht es möglich, Objekte wie Arrays aussehen zu lassen. Auch foreach lässt sich davon erfolgreich täuschen.

            Ansonsten reicht ein kleiner Typecast aus, um aus einem skalaren Wert vorübergehend ein Array zu machen und ein Array als solches zu belassen.

            $scalar = 42;  
            foreach ((array)$scalar as $value)  
              echo $value;
            

            echo "$verabschiedung $name";