Convertisseur xml <=> tableaux associatifs php

Soyez le premier à donner votre avis sur cette source.

Snippet vu 20 567 fois - Téléchargée 32 fois

Contenu du snippet

Cette librairie de quelque lignes permet de convertir un contenu XML en tableau associatif php et inversement.
Le plus gros du code concerne le sens XML => Assoc car il faut parser les balises XML.
Ceux qui souhaitent éviter d'utiliser xml_parse() pour une raison ou une autre y trouverons leur compte.

Source / Exemple :


<?

# lib.assoc.xml.php: Assoc <=> XML Conversion
#
# Date:     August, 29 2004
# Author:   YARD Mathieu / FAYA Solutions
# URL:      http://www.faya.fr/
# Contact:  lib.assoc.xml@faya.fr
#

define(AX_NAME_SUBKEY,'__name__');
define(AX_CONTENT_SUBKEY,'__content__');
define(AX_DEFNAME, 'unknown');

###### PRIVATE FUNCTIONS ###############################################################

# Is next element an xml nod ? (or is it a leaf...)
function is_balise_next($buf,$os)
{
  $l=strlen($buf);
  $x = $buf[$os];  
  while((ord($x)<=32)&&($os<$l)) $os++;
  return($x=='<');  
} 

# Parse strings like keyword="value"
function read_kv(&$os, $buf)
{
  $sw = 0; 
  $lb = strlen($buf);
  
  while($os<$lb)
  {
    $x = $buf[$os];
    if(($x=='/')||($x==' ')||($x=='>')) break;
    
    if($x == '=') 
      $sw = 1; 
    else 
      $val[$sw] .= $x;
    
    $os++;
  }
  
  list($k,$v) = $val;
  
  # Conditional quotes extraction
  if(ereg("^[\'\"](.*)[\'\"]$",$v,$tbl)) $v = $tbl[1];

  return(array($k=>$v));
}

###### PUBLIC FUNCTIONS #############################################################

# Create a root XML Object
function ax_root($name = null, $content = null)
{
  $assoc = array();
  if($name) $assoc[AX_NAME_SUBKEY] = $name;
  if($content) $assoc[AX_CONTENT_SUBKEY] = $content;   
  return($assoc);
}

# Create an XML Object
function &ax_balise(&$root, $name = null, $content = null)
{
  $assoc = ax_root($name,$content);
  return($root[] = $assoc);
}

# Generate XML code from an assoc array.
function assoc2xml(&$xmlbuf, $assoc)
{
  if(!is_array($assoc)) return true;  // Nothing to do
  
  # Object name extraction
  foreach($assoc as $ref => $content)
  {
    if(is_numeric($ref))
      assoc2xml(&$sub,$content);
    else
    {
      if($ref==AX_NAME_SUBKEY)
        $name = $content;
      elseif($ref==AX_CONTENT_SUBKEY)
        $bc = $content; 
      else
      {
        $out .= ' '.$ref;
        if($content) $out .= '="'.addslashes($content).'"';
      }
    } 
  }
  
  # If there's some subnods :  
  if($sub)
    $out .= '>'.$sub.'</'.$name.'>';    
  # If there's a content :
  elseif($bc)
    $out .= '>'.htmlentities($bc).'</'.$name.'>';
  # Empty marker :
  else $out .= '/>';
  
  $xmlbuf .= '<'.$name.$out;
  return(true); 
}

# Parsing XML into an assoc array.
function xml2assoc(&$assoc,$xmlbuf,$more=array())
{
  $lenbuf=strlen($xmlbuf); 
  $os=0;
  while($os<$lenbuf)
  {
    $x = $xmlbuf[$os];
    if(ord($x)>32)
    {
      # A marker should be found 
      if(!xa_xbalise_read($os, $assoc, $xmlbuf, $more)) return false;
    }    
    else $os++;     
  }    
  return true;
}

# XML marker parsing
//function xa_xbalise_read(&$os, &$assoc, $xmlbuf, $more = array())
function xa_xbalise_read(&$os, &$assoc, $xmlbuf, $more = array("strict"=>true))
{
  if(($x = $xmlbuf[$os++]) != '<') return false;
        
  $xbufsz = strlen($xmlbuf);

  # Read of marker name  
  while($os < $xbufsz)
  {
    $x = $xmlbuf[$os];
    if(($x == ' ')||($x == '/')||($x == '>')) break;
    $name .= $x;
    $os++;
  }
  
  $assoc[AX_NAME_SUBKEY] = $name;

  # Read of marker parameter (xxxxx="yyyyy")
  while($os<$xbufsz)
  {
    $x = $xmlbuf[$os];
    
    if($x=='/') 
      if($xmlbuf[$os+1]=='>') { $no_close=true; $os+=2; break; } # End of leaf marker
    if($x=='>') { $os++; break; }   # End of nod marker

    # Read unique assignement
    if(ord($x)>32) 
    {
      list($key,$value) = each(read_kv(&$os, $xmlbuf));
      if($key) $assoc[$key] = $value;
    }          
    else $os++;
  }
  

  # Spaces jumping
  while($os<$xbufsz) 
  {
    $x=$xmlbuf[$os];
    if(ord($x)>32) break; 
    $os++;
  }
  
  if($no_close) return true;
  
  # Marker content extraction
  $content = substr($xmlbuf,$os);

  # Ending marker detection
  $closing = '</'.$name.'>'; $lc = strlen($closing);

  if(false === ($endpos = strpos($content,$closing)))
  {
    if($more['strict']) return false;  # end of marker not found !
    $endpos =  strlen($content);
  }
  $content = substr($content,0,$endpos);
  $startpos = $os;

  # Content or submarker is coming next?
  if(is_balise_next($content,0))
  {
    while(($os-$startpos) < $endpos)
    {
      $tmp=array();
      if(!xa_xbalise_read(&$os,&$tmp,$xmlbuf,$more)) return false; # Erroneous submarker !
      $assoc[] = $tmp;
    }
  }
  else
  {
    $assoc[AX_CONTENT_SUBKEY] = $content;
    $os += $endpos;
  }

  # If can't find ending marker
  if(($xbufsz - $os - $lc)<0) return($more['strict']?false:true);
  
  $os += $lc;
 
  return true;
}

###### TESTING ################################################################

# This part demonstrates how to use this library.

function printr ( $var, $do_not_echo = false )
{
   ob_start();
   print_r($var);
   $code =  htmlentities(ob_get_contents());
   ob_clean();
   if ( !$do_not_echo )
   {
       echo "<pre>$code</pre>";
   }
   return $code;
}

function xa_test()
{
  # 1. CONSTRUCT A SIMPLE PHP XML ASSOC ARRAY
  $root = ax_root('animals');         # XML root marker

  $dogs = ax_balise($root, "dogs"); # XML child
  $dogs['kinds'] = 2;                 # XML marker property
  $dogs['size'] = "big";

  $labrador = ax_balise($dogs, "labrador");
  $labrador[retreiver] = ''; 

  $chihuahua = ax_balise($dogs, "chihuahua", "charly");

  $cats = ax_balise($root, "cats");

  $persian = ax_balise($cats, "persian");
  $siamese = ax_balise($cats, "siamese");

  $root['kinds'] = 'dogs,cats';

  $staff = ax_balise($dogs, "staff");
  $staff[weight] = 40;
  
  # 2. PHP XML ASSOC ARRAY => XML BUFFER

  printr($root);
  echo "<hr>";
  
  assoc2xml($xmlbuf,$root);
  
  echo("XML: ".htmlentities($xmlbuf)."<br/>");

  # 3. XML BUFFER => PHP XML ASSOC ARRAY (check)

  echo "<hr>";
  
  xml2assoc($assoc,$xmlbuf);

  echo("Check: ".(($assoc == $root)?'ok':'non')."<br/>");  

  printr($root);

}

Conclusion :


Tout le fichier est commenté en anglais et divisé en 3 parties: fonctions privées, fonctions publiques et routine de test.
La section routine de test est prévue pour vous faire une démonstration de l'utilisation de la librairie.

A voir également

Ajouter un commentaire

Commentaires

cs_GRenard
Messages postés
1663
Date d'inscription
lundi 16 septembre 2002
Statut
Membre
Dernière intervention
30 juillet 2008
1 -
Tout ce qui fonctionne sous php4 devrait fonctionner sous php5 (avec les mêmes configurations)
antebios
Messages postés
6
Date d'inscription
dimanche 23 mars 2003
Statut
Membre
Dernière intervention
14 juin 2005
-
Quand je fais un copier collé je me retrouve avec un # devant chaque ligne...intestable a moins de s'amuser à effacer les # 1 par 1...
cs_GRenard
Messages postés
1663
Date d'inscription
lundi 16 septembre 2002
Statut
Membre
Dernière intervention
30 juillet 2008
1 -
c'est firefox qui fait ca... prend Internet Explorer ou autre... ou télécharge le zip quand il y en a un (ici yen a pas... sorry :P)
antebios
Messages postés
6
Date d'inscription
dimanche 23 mars 2003
Statut
Membre
Dernière intervention
14 juin 2005
-
Ha oui en effet.
Merci.
Bizarre qu'il fasse ça.
mabeur
Messages postés
4
Date d'inscription
jeudi 7 juillet 2005
Statut
Membre
Dernière intervention
17 novembre 2005
-
Hmm comment fait on pour spécifier un fichier xml a convertir en array ?
Commenter la réponse de cs_GRenard

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.