PHP propose la classe XMLWriter qui permet de produire des données en XML. Par exemple le code suivant :
$w = new XMLWriter(); $w->openUri('php://stdout'); $w->setIndent(true); $w->setIndentString(' '); $w->startDocument('1.0', 'utf-8', true); $w->writePI('xml-stylesheet', 'type="text/xsl" media="screen" href="test.xsl"'); $w->writeComment('Exemple'); $w->startElementNS('rdf', 'RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'); $w->writeAttributeNS('xmlns', 'skos', null, 'http://www.w3.org/2004/02/skos/core#'); $w->startElement('skos:Concept'); $w->writeAttribute('rdf:about', '#truc'); $w->startElement('skos:prefLabel'); $w->writeAttribute('xml:lang', 'fr'); $w->text('truc'); $w->endElement(); $w->endElement(); $w->startElement('skos:Concept'); $w->writeAttribute('rdf:about', '#bidule'); $w->startElement('skos:prefLabel'); $w->writeAttribute('xml:lang', 'fr'); $w->text('bidule'); $w->endElement(); $w->endElement(); $w->startElement('skos:Concept'); $w->writeAttribute('rdf:about', '#chouette'); $w->startElement('skos:prefLabel'); $w->writeAttribute('xml:lang', 'fr'); $w->text('chouette'); $w->endElement(); $w->endElement(); $w->endElement(); $w->endDocument(); $w->flush();
produira :
<?xml version="1.0" encoding="UTF-8" standalone="1"?> <?xml-stylesheet type="text/xsl" media="screen" href="test.xsl"?> <!--Example--> <rdf:RDF xmlns:skos="http://www.w3.org/2004/02/skos/core#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <skos:Concept rdf:about="#truc"> <skos:prefLabel xml:lang="fr">truc</skos:prefLabel> </skos:Concept> <skos:Concept rdf:about="#bidule"> <skos:prefLabel xml:lang="fr">bidule</skos:prefLabel> </skos:Concept> <skos:Concept rdf:about="#chouette"> <skos:prefLabel xml:lang="fr">chouette</skos:prefLabel> </skos:Concept> </rdf:RDF>
Et bien voici la classe JSONWriter qui fonctionne exactement de la même manière à la différence près qu'elle produit du JSON à la place du XML. Il suffit simplement de remplacer la construction par :
require_once 'JSONWriter.php'; $w = new JSONWriter;
Ce qui permettra de générer :
{ "version": "1.0", "encoding": "utf-8", "standalone": "yes", "<?xml-stylesheet": { "$t": "type=\"text\/xsl\" media=\"screen\" href=\"test.xsl\"" }, "rdf$RDF": { "xmlns$rdf": "http:\/\/www.w3.org\/1999\/02\/22-rdf-syntax-ns#", "xmlns$skos": "http:\/\/www.w3.org\/2004\/02\/skos\/core#", "skos:Concept": [ { "rdf:about": "#truc", "skos:prefLabel": { "xml:lang": "fr", "$t": "truc" } }, { "rdf:about": "#bidule", "skos:prefLabel": { "xml:lang": "fr", "$t": "bidule" } }, { "rdf:about": "#chouette", "skos:prefLabel": { "xml:lang": "fr", "$t": "chouette" } } ] } }
Mapping JSON - XML
La conversion XML vers JSON n'est pas à ma connaissance normalisée et il existe donc différente façon de faire. Si le sujet vous intéresse je vous invite à lire cet article : Converting XML to JSON. Celui-ci résume assez bien les différentes pratiques. La classe JSONWriter implémente actuellement la méthode utilisée par Google et décrite sur la page Using JSON in the Google Data Protocol
Problèmes
La méthode Google est simple, facile à comprendre mais elle est limitée. Elle n'intègre pas les Processsing Instruction ni les DTD mais surtout elle ne permet pas l'usage pour une balise d'un attribut et d'une sous balise de même nom.
La classe JSONWriter souffre également de ce défaut, elle ne traite pas non plus les DTD mais par contre elle traite parfaitement les PI en réalisant une association '<?target_of_pi' : 'valeur_pi'.
Évolution
Je ne ferai probablement pas évoluer cette classe, car elle couvre le besoin pour lequel je l'ai écrit. Mais on peut imaginer qu'elle puisse générer du Json façon Yahoo. Et que la méthode flush soit réellement active (Dans la version 1.0, les "flush" intermédiaire sont simplement ignorés).
Téléchargement et code source
Le code source est disponible sur GitHub : http://github.com/touv/JSONWriter
Ou, on peut directement l'installer avec PEAR en s'abonnant au Channel Respear :
% pear channel-discover pear.respear.net % pear install respear/JSONWriter
Merci beaucoup! Cette classe couvre mon besoin aussi!
RépondreSupprimerJe remarque que les contenus des balises XML sont transformés en JSON vers la combinaison clé / valeur "$t" / "valeur".
RépondreSupprimerC'est pas forcément très pratique à l'usage mais j'imagine que c'est obligatoire ?
Obligatoire si on veut respecter la documentation google qui indique "Text values of tags are converted to $t properties." cf. http://code.google.com/apis/gdata/docs/json.html
RépondreSupprimerMaintenant, va savoir pourquoi les ingénieurs de Google ont choisi cette syntaxe...