SimpleXML -> Array

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • SimpleXML -> Array

    Guten Tag,

    folgendes XML-Dokument:
    Code:
    <Collection>
      <DVD>
        <ProfileTimestamp>2010-06-09T19:35:47.000Z</ProfileTimestamp>
        <ID>4010232044778.5</ID>
        [COLOR=Red]<MediaTypes>
          <DVD>true</DVD>
          <HDDVD>false</HDDVD>
          <BluRay>false</BluRay>
        </MediaTypes>[/COLOR]
      <DVD>
    </Collection>
    parse ich mit Hilfe von SimpleXML
    PHP-Code:
    $xml simplexml_load_file('test.xml');
    $c_dvd 0;
    /** Foreach root element **/
    foreach($xml as $key => $value){
        
    /** foreach element on level 1 **/
        
    foreach($value as $key => $value1) {        
            
    $dvds[$c_dvd][$key] = (string) $value1;
            
    /** If element has children **/
            
    if(count($value1) > 0) { 
                
    /** foreach element on level 2**/
                
    foreach($value1 as $key1 => $value2) {
                    
    $dvds[$c_dvd][$key][$key1] = (string) $value2;
                }
            }
        }    
        
    $c_dvd++;

    Das kommt dabei heraus wenn ich mir das Array $dvds mit print_r ausgeben lasse
    Code:
    Array ([0] => Array (
        [ProfileTimestamp] => 2010-06-09T19:35:47.000Z
        [ID] => 4010232044778.5
        [COLOR=Red][MediaTypes] => f
        
        
       
        [/COLOR][COLOR=Red][UPC] => 4-010232-044778[/COLOR]
      )
    )
    Und genau da liegt das Problem. Bei MediaTypes müssten eigentlich 3 Schlüssel mit den entsprechenden Werten auftauchen. Wenn ich mir mit einem echo die Werte $key1 und $value2 ausgeben lassen funktioniert das auch. Eigentlich müsste da nach meinem Verständnis so etwas herauskommen:
    Code:
    Array ([0] => Array (
        [ProfileTimestamp] => 2010-06-09T19:35:47.000Z
        [ID] => 4010232044778.5
        [COLOR=Red][MediaTypes] => array (
          [/COLOR][COLOR=Red][DVD]=>true
          [HDDVD]=>false
          [BluRay]=>false[/COLOR] [COLOR=Red]
        )
        [/COLOR][COLOR=Red][UPC] => 4-010232-044778[/COLOR]
      )
    )
    Oder etwa nicht?

    Viele Dank für's Durchlesen.
    Nedan

  • #2
    Kannst du noch ne Testausgabe von $xml posten?
    Wiese parst du das ganze noch mal von Hand?

    Deine Testausgaben wirken nicht plausibel, weil da Leerzeichen drin sind, die print_r() niemals ausgeben würde.

    Die Abfrage if(count($value1) > 0) { sollte eigentlich schon kommen, bevor du den Wert ins Array speicherst.
    Zuletzt geändert von TobiaZ; 25.09.2011, 16:10.

    Kommentar


    • #3
      Hi,

      ich habe den Fehler gefunden. Siehe weiter unten.
      zu den Fragen:
      Testausgabe direkt nach simplexml_load_file
      Code:
      SimpleXMLElement Object (     
        [DVD] => SimpleXMLElement Object (             
          [ProfileTimestamp] => 2010-06-09T19:35:47.000Z             
          [ID] => 4010232044778.5             
          [MediaTypes] => SimpleXMLElement Object  (                     
            [DVD] => true                     
            [HDDVD] => false                     
            [BluRay] => false
          )          
        )  
      )
      Warum ich das ganze noch mal von Hand parse?
      Weil nachher sowas im XML kommt:
      Code:
      <Actors>
        <Divider Caption="1. Pilot: Kaltgestellt" Type="Episode"/>
        <Actor FirstName="Jeffrey" MiddleName="" LastName="Donovan".../>
        <Actor FirstName="Gabrielle" MiddleName="" LastName="Anwar".../>
        <Divider Caption="2. Ausgetrickst " Type="Episode"/>
         ...
      </Actors>
      Der Divider hat keinerlei Kindelemente ist aber eine Unterteilung. Und die soll beibehalten werden.
      SimpleXML macht, ohne das von Hand parsen, daraus:
      Code:
      [Actors] => SimpleXMLElement Object (                     
        [Divider] => Array (                             
          [0] => SimpleXMLElement Object (                                     
            [@attributes] => Array (                                             
              [Caption] => 1. Pilot: Kaltgestellt                                             
              [Type] => Episode                                         
            )                                  
          )                              
         [1] => SimpleXMLElement Object (                                     
           [@attributes] => Array (                                             
             [Caption] => 2. Ausgetrickst                                             
             [Type] => Episode
           )                                  
         )                              
       )                      
      [Actor] => Array (                             
        [0] => SimpleXMLElement Object (                                     
          [@attributes] => Array (                                             
            [FirstName] => Jeffrey                                             
            [MiddleName] =>                                              
            [LastName] => Donovan
          )                                  
        )                              
        [1] => SimpleXMLElement Object (                                     
          [@attributes] => Array (                                             
            [FirstName] => Gabrielle                                             
            [MiddleName] =>                                              
            [LastName] => Anwar                                         
          )                                  
        )
      )
      So geht die Zuordnung von Divider und Schauspieler verloren.
      Vielleicht kennst du eine besser Möglichkeit mit XML was dann in die Datenbank geschrieben wird. Ich bin offen für neues =)

      Damit allerdings kann ich nichts anfangen. Kannst du mir genau erklären was du meinst?
      Deine Testausgaben wirken nicht plausibel, weil da Leerzeichen drin sind, die print_r() niemals ausgeben würde.
      Lösung
      Es war mal wieder ein Denkfehler (rot markiert).
      Code:
      /** foreach element on level 1 **/
      [COLOR=Red]foreach($value as $key => $value1) {        
        $dvds[$c_dvd][$key] = (string) $value1;[/COLOR]
          /** If element has children **/
          if(count($value1) > 0) { 
            /** foreach element on level 2**/
            foreach($value1 as $key1 => $value2) {
              $dvds[$c_dvd][$key][$key1] = (string) $value2;
            }
          }
        }
      }
      Denkfehler deswegen:
      $key ist dem Fall Mediatype und dieses Element hat weder Attribute noch Werte, sondern nur Kindelemente. Ich schreibe aber fröhlich in $value1 und das ist dann das komplette SimpleXML Object für MediaTypes:
      Code:
      object(SimpleXMLElement)#5 (3) {   
        ["DVD"]=>   string(4) "true"   
        ["HDDVD"]=>   string(5) "false"   
        ["BluRay"]=>   string(5) "false" 
      }
      Also muss ich, bevor ich die erste Ebene in das Array schreibe überprüfen ob das Element Kindelemente hat oder nicht.
      So funktioniert es dann:
      PHP-Code:
      foreach($xml as $key => $value){
          
      /** foreach element on level 1 **/
          
      foreach($value as $key => $value1) {
              
      /** If element has children **/
              
      if(count($value1) > 0) {
                  
      /** foreach element on level 2**/
                  
      foreach($value1 as $key1 => $value2) {
                      
      $dvds[$c_dvd][$key][$key1] = (string)$value2;                
                  }
              } else {
                  
      $dvds[$c_dvd][$key] = (string)$value1;
              }
          }    
          
      $c_dvd++;

      Kommentar

      Lädt...
      X