     1: <?php
     2:
     3: class RESTian_Application_Xml_Parser extends RESTian_Parser_Base {
     4:   /**
     5:    * Returns an object or array of stdClass objects from an XML string.
     6:    *
     7:    * @note Leading and trailing space are trim()ed.
     8:    *
     9:    * @see https://www.bookofzeus.com/articles/convert-simplexml-object-into-php-array/
    10:    * @see https://php.net/manual/en/function.simplexml-load-string.php
    11:    * @see https://hakre.wordpress.com/2013/02/12/simplexml-type-cheatsheet/
    12:    *
    13:    * @param string|SimpleXMLElement $body
    14:    * @return array|object A(n array of) stdClass object(s) with structure dictated by the passed XML string.
    15:    */
    16:   function parse( $body ) {
    17:     if ( empty( $body ) )
    18:       return array();
    19:
    20:     $is_array = false;
    21:     $xml = is_string( $body ) ? new SimpleXMLElement( $body ) : $body;
    22:
    23:     $data = (array)$xml->attributes();
    24:     if ( 0 == count( $data ) )
    25:       $data['@attributes'] = array();
    26:
    27:     /**
    28:      * @var SimpleXMLElement $element
    29:      */
    30:     foreach ($xml as $element) {
    31:       $tag = $element->getName();
    32:       $e = get_object_vars( $element );
    33:       if ( ! empty( $e ) ) {
    34:         $subset = $element instanceof SimpleXMLElement ? $this->parse( $element ) : $e;
    35:       } else {
    36:         $subset = trim( $element );
    37:       }
    38:       if ( ! isset( $data[$tag] ) ) {
    39:         $data[$tag] = $subset;
    40:       } else {
    41:         if ( is_array( $data[$tag] ) ) {
    42:           $data[$tag][] = $subset;
    43:         } else {
    44:           /**
    45:            * Convert to an an array because we are seeing duplicate tags.
    46:            */
    47:           $data[$tag] = array( $data[$tag], $subset );
    48:           $is_array = true;
    49:         }
    50:       }
    51:     }
    52:     return $is_array ? $data : (object)$data;
    53:   }
    54: }
    55: