Salve a tutti!
Questo è un topic per coloro che come me odiano l'xml, ma sono costretti a lavorarci a stretto contatto lo stesso..

Insoddisfatto da SimpleXml e dal suo trattamento approssimativo degli attributi, mi sono buttato nella creazione di due classi per la lettura / scrittura di questo formato..
Non leggono e non scrivono direttamente i file, ma ricevono in input l'xml sotto forma di stringa. Questo per evitare di utilizzare per forza un file vero, e non magari uno "finto" (magari lavorando con le api di un web service?).

Non ho preso spunto da nulla di esistente, quindi se trovate che vi sembra somigli a qualcos'altro, giuro che è una coincidenza!

Ecco le due classi (forse l'inglese dei commenti phpDoc non è perfetto )

esXmlParser
Codice PHP:

/**
 * esXmlParser class
 * This class parses a xml string into an object struct
 *
 * @author Davide Borsatto
 * @version 0.8
 * @package xml 
 */

class esXmlParser
{

  
/**
   * Parses an xml string into an object
   *   
   * @access public
   * @param string $source The xml string
   * @return mixed The parsed xml string      
   */           
  
public static function parse($source)
  {
    return 
self::xmlToObject($source);
  }

  
/**
   * Converts an xml string into an object struct
   * 
   * @access public
   * @param string $xmlData The xml string
   * @return esXmlNode The parsed xml
   */
  
private static function xmlToObject($xmlData)
  {
    
$xmlValues self::parseXmlIntoStruct($xmlData);
    
$root = new esXmlNode();
    
$root->setName('root');
    
$actualLevel 1;
    
$actualNode $root;
    
$stack = array();
    
$stack[1] = $root;
    foreach (
$xmlValues as $element)
    {
      if (
$element['type'] == 'close')
      {
        continue;
      }
      
$node = new esXmlNode();
      
$node->setName($element['tag']);
      if (
array_key_exists('attributes'$element))
      {
        
$node->setAttributes($element['attributes']);
      }
      if (
array_key_exists('value'$element))
      {
        
$node->setValue($element['value']);
      }
      
$level $element['level'];
      if (
$level $actualLevel)
      {
        
$stack[$level] = $actualNode;
      }
      
$stack[$level]->addSon($node);
      
$actualNode $node;
      
$actualLevel $element['level'];
    }
    
$sons $root->getSons();
    return 
$sons[0];
  }

  
/**
   * Parses xml using native php functions
   *
   * @access public
   * @param string $xmlData The string to be parsed
   * @return array The parsed xml
   */
  
private static function parseXmlIntoStruct($xmlData)
  {
    
$parser xml_parser_create('');
    
xml_parser_set_option($parserXML_OPTION_TARGET_ENCODING'UTF-8');
    
xml_parser_set_option($parserXML_OPTION_CASE_FOLDING0);
    
xml_parser_set_option($parserXML_OPTION_SKIP_WHITE1);
    
xml_parse_into_struct($parser$xmlData$xmlValues);
    
xml_parser_free($parser);
    return 
$xmlValues;
  }