Postanowiłem sobie zrobić parsera plików XML wykorzystując wbudowany w PHP5 SimpleXML. Miałby mi posłużyć za parsowanie plików konfiguracyjnych i generowanie z drzewa XML tablicy php - i właśnie tu pojawia się problem. Zaglądnąłem do manuala i w komentarzach znalazłem funkcję simplexml_to_array(), ale ta nie działała całkiem dobrze... Później natrafiłem w manualu na sekcję SPL i tam znalazłem iterator SimpleXML (SimpleXMLIterator - niestety jeszcze nie do końca udokumentowany) tak więc postanowiłem wykorzystać go do generowania tablicy. Opierając się na przykładowej implementacji RecursiveDirectoryIterator zamieszczonej w komentarzach napisałem coś takiego:
  1. <?php
  2.  
  3. function XMLToArray( $Iterator )
  4. {
  5. $array = array();
  6.  
  7. while ( $Iterator->valid() )
  8. {
  9. if ( $Iterator->hasChildren() === true )
  10. {
  11. $array[ $Iterator->key() ] = XMLToArray( $Iterator->getChildren() );
  12.  
  13. $Iterator->next();
  14. }
  15. else
  16. {
  17. if ( isSet( $array[ $Iterator->key() ] ) === false )
  18. {
  19. $_key  = $Iterator->key();
  20. $_value = $Iterator->current();
  21.  
  22. $Iterator->next();
  23.  
  24. if ( $Iterator->key() == $_key )
  25. {
  26. $array[ $_key ] = array( (string)$_value );
  27. }
  28. else
  29. {
  30. $array[ $_key ] = (string)$_value;
  31. }
  32. }
  33. else
  34. {
  35. $array[ $Iterator->key() ][] = (string)$Iterator->current();
  36.  
  37. $Iterator->next();
  38. }
  39. }
  40. }
  41.  
  42. return $array;
  43. }
  44.  
  45. ?>
Wykorzystuję tą funkcję w ten sposób:
  1. <?php
  2.  
  3. $Iterator = new SimpleXMLIterator( file_get_contents( './dcc.xml' ) );
  4. $Iterator->rewind();
  5.  
  6. printArray( XMLToArray( $Iterator ) );
  7.  
  8. ?>
A oto przykładowy plik XML (dcc.xml), który parsuje:
  1. <?xml version="1.0" encoding="iso-8859-2" ?>
  2.  
  3. <domaincheckerconfiguration>
  4.      <language>pl</language>
  5.      <allowdomains>
  6.            <domain>pl</domain>
  7.            <domain>net.pl</domain>
  8.            <domain>com.pl</domain>
  9.            <domain>com</domain>
  10.            <domain>net</domain>
  11.      </allowdomains>
  12. </domaincheckerconfiguration>
Po uruchomieniu funkcji otrzymuję niepełny wynik:
Kod
Array
(
    [language] => pl
    [allowdomains] => Array
        (
        )

)
A powinien być taki:
Kod
Array
(
    [language] => pl
    [allowdomains] => Array
        (
            [0] => pl
            [1] => net.pl
            [2] => com.pl
            [3] => com
            [4] => net
        )

)
Po drugim zagłębieniu (root->allowdomains) metoda SimpleXMLIterator::valid zwraca FALSE - nie wiem dlaczego sad.gif

Prosiłbym o pomoc sadsmiley02.gif