Transformer un source JS ou JSON en XML

En ce moment, au travail je dois réaliser des flux RSS constitué d’éléments que je récupère ne JavaScript.

Un flux RSS, c’est en réalité un flux XML. Je ferai bien un article dessus, mais l’article wikipedia explique plutôt bien le principe : https://fr.wikipedia.org/wiki/RSS#Aspects_techniques

Donc j’ai un objet JS, et je dois construire un fichier XML.

J’ai introduit la situation via la tâche que je dois réaliser au travail, mais il peut en avoir d’autre :

  • Génération de fichiers de configuration pour un logiciel ayant besoin de fichiers XML.
  • Stockage de données utilisant le format XML.
  • Communication à un service n’acceptant que le format XML.

J’ai donc décidé de réaliser un article présentant une méthode permettant de transformer un flux JSON en un flux XML.

L’origine du flux JSON sera une API donnant des renseignement sur les derniers lancement des fusées Space X : https://github.com/r-spacex/SpaceX-API/blob/master/docs/v4/launches/latest.md

Le code que je vais présenté sera réalisé en Node JS, et nécessitera l’intégration de 2 bibliothèques :

Pour cela on réalise dans le terminal de commande :

npm install node-fetch xml-js

Ensuite je vous présente tout d’abord le code dans son intégralité :

const convert = require('xml-js')
const fs = require('fs')
const fetch = require('node-fetch')

let launchInfos = {}
const options = {
  compact: true,
  spaces: 4,
  indentAttributes: true,
}

async function getLastLaunch() {
  try {
    const response = await fetch('https://api.spacexdata.com/v4/launches/latest')
    launchInfos = await response.json()
    launchInfosXml = convert.js2xml(launchInfos, options)
    fs.writeFileSync('launchInfos.json', JSON.stringify(launchInfos, null, '\t'))
    fs.writeFileSync('launchInfos.xml', launchInfosXml)
  } catch (error) {
    console.error("La réception des données de l'api a échoué : ", error)
  }
}

getLastLaunch()

Donc tout d’abord on récupère les informations du lancement dans un objet JSON :

const response = await fetch('https://api.spacexdata.com/v4/launches/latest')
launchInfos = await response.json()

La configuration de la conversion est défini dans la variable options :

const options = {
  compact: true,
  spaces: 4,
  indentAttributes: true,
}

Ensuite on utilise simplement la méthode js2xml() qui nous est fourni par la bibliothèque xml-js :

launchInfosXml = convert.js2xml(launchInfos, options)

Et pour finir, on va enregistrer nos données dans 2 fichiers différents (l’un en JSON et l’autre en XML) :

fs.writeFileSync('launchInfos.json', JSON.stringify(launchInfos, null, '\t'))
fs.writeFileSync('launchInfos.xml', launchInfosXml)

Et voici ce qu’on a :

launchInfos.json

{
	"fairings": {
		"reused": null,
		"recovery_attempt": true,
		"recovered": null,
		"ships": [
			"5ea6ed2e080df4000697c908"
		]
	},
	"links": {
		"patch": {
			"small": "https://images2.imgbox.com/9a/96/nLppz9HW_o.png",
			"large": "https://images2.imgbox.com/d2/3b/bQaWiil0_o.png"
		},
		"reddit": {
			"campaign": "https://www.reddit.com/r/spacex/comments/i63bst/starlink_general_discussion_and_deployment_thread/",
			"launch": "https://www.reddit.com/r/spacex/comments/iip8h3/rspacex_starlink11_launch_discussion_updates/",
			"media": "https://www.reddit.com/r/spacex/comments/ij8mxf/rspacex_starlink11_saocom_1b_media_thread/",
			"recovery": null
		},
		"flickr": {
			"small": [],
			"original": []
		},
		"presskit": null,
		"webcast": "https://youtu.be/_j4xR7LMCGY",
		"youtube_id": "_j4xR7LMCGY",
		"article": null,
		"wikipedia": "https://en.wikipedia.org/wiki/Starlink"
	},
	"static_fire_date_utc": null,
	"static_fire_date_unix": null,
	"tbd": false,
	"net": false,
	"window": null,
	"rocket": "5e9d0d95eda69973a809d1ec",
	"success": true,
	"details": "This mission will launch the eleventh batch of operational Starlink satellites, which are expected to be version 1.0, from SLC-40, Cape Canaveral Air Force Station. It is the twelfth Starlink launch overall. The satellites will be delivered to low Earth orbit and will spend a few weeks maneuvering to their operational altitude of 550 km. The booster for this mission is expected to land on an ASDS.",
	"crew": [],
	"ships": [
		"5ea6ed2e080df4000697c908",
		"5ea6ed2f080df4000697c90b",
		"5ee68c683c228f36bd5809b5"
	],
	"capsules": [],
	"payloads": [
		"5ef6a4600059c33cee4a829e"
	],
	"launchpad": "5e9e4502f509094188566f88",
	"auto_update": true,
	"failures": [],
	"flight_number": 102,
	"name": "Starlink-11 (v1.0)",
	"date_utc": "2020-09-03T12:46:00.000Z",
	"date_unix": 1599137160,
	"date_local": "2020-09-03T08:46:00-04:00",
	"date_precision": "hour",
	"upcoming": false,
	"cores": [
		{
			"core": "5ef670f10059c33cee4a826c",
			"flight": 2,
			"gridfins": true,
			"legs": true,
			"reused": true,
			"landing_attempt": true,
			"landing_success": true,
			"landing_type": "ASDS",
			"landpad": "5e9e3032383ecb6bb234e7ca"
		}
	],
	"id": "5ef6a1e90059c33cee4a828a"
}

launchInfos.xml

<fairings>
    <reused/>
    <recovery_attempt>true</recovery_attempt>
    <recovered/>
    <ships>5ea6ed2e080df4000697c908</ships>
</fairings>
<links>
    <patch>
        <small>https://images2.imgbox.com/9a/96/nLppz9HW_o.png</small>
        <large>https://images2.imgbox.com/d2/3b/bQaWiil0_o.png</large>
    </patch>
    <reddit>
        <campaign>https://www.reddit.com/r/spacex/comments/i63bst/starlink_general_discussion_and_deployment_thread/</campaign>
        <launch>https://www.reddit.com/r/spacex/comments/iip8h3/rspacex_starlink11_launch_discussion_updates/</launch>
        <media>https://www.reddit.com/r/spacex/comments/ij8mxf/rspacex_starlink11_saocom_1b_media_thread/</media>
        <recovery/>
    </reddit>
    <flickr>
    </flickr>
    <presskit/>
    <webcast>https://youtu.be/_j4xR7LMCGY</webcast>
    <youtube_id>_j4xR7LMCGY</youtube_id>
    <article/>
    <wikipedia>https://en.wikipedia.org/wiki/Starlink</wikipedia>
</links>
<static_fire_date_utc/>
<static_fire_date_unix/>
<tbd>false</tbd>
<net>false</net>
<window/>
<rocket>5e9d0d95eda69973a809d1ec</rocket>
<success>true</success>
<details>This mission will launch the eleventh batch of operational Starlink satellites, which are expected to be version 1.0, from SLC-40, Cape Canaveral Air Force Station. It is the twelfth Starlink launch overall. The satellites will be delivered to low Earth orbit and will spend a few weeks maneuvering to their operational altitude of 550 km. The booster for this mission is expected to land on an ASDS.</details>
<ships>5ea6ed2e080df4000697c908</ships>
<ships>5ea6ed2f080df4000697c90b</ships>
<ships>5ee68c683c228f36bd5809b5</ships>
<payloads>5ef6a4600059c33cee4a829e</payloads>
<launchpad>5e9e4502f509094188566f88</launchpad>
<auto_update>true</auto_update>
<flight_number>102</flight_number>
<name>Starlink-11 (v1.0)</name>
<date_utc>2020-09-03T12:46:00.000Z</date_utc>
<date_unix>1599137160</date_unix>
<date_local>2020-09-03T08:46:00-04:00</date_local>
<date_precision>hour</date_precision>
<upcoming>false</upcoming>
<cores>
    <core>5ef670f10059c33cee4a826c</core>
    <flight>2</flight>
    <gridfins>true</gridfins>
    <legs>true</legs>
    <reused>true</reused>
    <landing_attempt>true</landing_attempt>
    <landing_success>true</landing_success>
    <landing_type>ASDS</landing_type>
    <landpad>5e9e3032383ecb6bb234e7ca</landpad>
</cores>
<id>5ef6a1e90059c33cee4a828a</id>

La conversion est plutôt propre ! Cependant il n’y a pas de racine encadrant le tout, ce qui en fonction de l’usage peut être une difficulté.

Pour marque-pages : Permaliens.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *