Convertisseur xml <=> tableaux associatifs php

Soyez le premier à donner votre avis sur cette source.

Snippet vu 20 592 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 -
Ca n'existe pas des fonctions publics; privées comme ca... Si tu veux le faire, tu dois faire une classe.
fass2q
Messages postés
3
Date d'inscription
mercredi 11 février 2004
Statut
Membre
Dernière intervention
3 décembre 2004
-
Oui, je sais bien... c'est juste pour indiquer à l'utilisateur final du code quels fonctions lui sont déstinées et quelles fonctions servent à la librairie proprement dite.
ltnweb
Messages postés
1
Date d'inscription
vendredi 21 mars 2003
Statut
Membre
Dernière intervention
29 septembre 2004
-
C'est beau tout ça mais ça s'utilise comment ????!
cs_GRenard
Messages postés
1663
Date d'inscription
lundi 16 septembre 2002
Statut
Membre
Dernière intervention
30 juillet 2008
1 -
C'est vrai que c'est pas énormément documenté ... si jveux passer un code xml c'est ou que j'envoie ca... de plus, si jamais dans mon code il y a ">bla ca va planter je crois...
De plus tu utilises du allow_call_time_pass_reference à On, et c'est rendu désuet... si ta fonction possède le & tu n'as pas besoin de lui passer directement le & lorsque tu appelles la fonction...
Tu devrais peut-etre lire ca http://www.phpcs.com/code.aspx?ID=24870
et pour une autre sour de xml (par contre, elle ne fait que convertir de xml->tableau)
http://www.phpcs.com/code.aspx?ID=24639
fass2q
Messages postés
3
Date d'inscription
mercredi 11 février 2004
Statut
Membre
Dernière intervention
3 décembre 2004
-
Créez un php du style

<?

require_once("lefichierkésurcettepage.php");

xa_test();

?>


et alors tout deviendra clair ;o)

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.