/ / Construction ordonnée JSON en perl - json, perl, d3.js

Bâtiment commandé JSON en Perl - Json, Perl, D3.js

J'ai un peu de violon avec JSON et D3, essayant de représenter certaines informations d'utilisation du disque dans un style "bulle".

Sur la base de cela initialement: http://bl.ocks.org/mbostock/4063269

Le JSON est assez simple - les données hiérarchiques ressemblent un peu à ceci:

http://bl.ocks.org/mbostock/raw/4063530/flare.json

{
"name": "flare",
"children": [
{
"name": "analytics",
"children": [
{
"name": "cluster",
"children": [
{"name": "AgglomerativeCluster", "size": 3938},
{"name": "CommunityStructure", "size": 3812},
{"name": "HierarchicalCluster", "size": 6714},
{"name": "MergeEdge", "size": 743}
]
}
]
}
]
}

Maintenant, ce que je suis en essayant faire est de prendre un quotas rapport à partir d'un NetApp - sous forme XML.

J'ai plusieurs fichiers XML "par serveur" qui ressemblent approximativement à:

<quotas>
<quota>
<quota-target>/vol/vol1/qtree1</quota-target>
<volume>vol1</volume>
<disk-used>554444</disk-used>
<disk-limit>2000000</disk-limit>
</quota>
<quota>
<quota-target>/vol/vol1/qtree2</quota-target>
<volume>vol1</volume>
<disk-used>1235655</disk-used>
<disk-limit>2000000</disk-limit>
</quota>
<quota>
<quota-target>/vol/vol2/qtree1</quota-target>
<volume>vol2</volume>
<disk-used>987664</disk-used>
<disk-limit>2000000</disk-limit>
</quota>
</quotas>

Ce que j'essaie de faire, c'est d'assembler du JSON pour une utilisation avec D3 qui est hiérarchique:

  • site
  • serveur
  • le volume
  • quota-cible
  • disque utilisé

Je vais bien avec une boucle foreach:

#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
use JSON;

my %sites = (
"site1" => [qw ( servera serverb )],
"site2" => [qw ( s2serverc s2serverd)],
);

my $data;
$data->{"name"} = "quotas";
foreach my $sitename ( keys %sites ) {
my $site = { "name" => $sitename };
push( @{ $data->{"children"} }, $site );
foreach my $server ( @{ $sites{$sitename} } ) {
my $server = { "name" => $server };
push( @{ $site->{"children"} }, $server );

$twig->parsefile("$server.quotas.xml");
foreach my $quota ( $twig->get_xpath("//quota") ) {
push(
@{ $server->{"children"} },
{   "name" => $quota->first_child_text("quota-target"),
"size" => $quota->first_child_text("disk-used")
}
)

}
}
}

open( my $output, ">", "quotas.json" ) or die $!;
print {$output} to_json( $data, { "pretty" => 1 } );
close($output);

Cela fonctionne globalement et me produit de jolies images.

Cependant, j'ai deux problèmes:

L'ordre du JSON change à chaque exécution, car j'utilise un hachage. Bien que ce ne soit pas un stopper, existe-t-il un moyen d'appliquer un ordre dans la sortie JSON? (Pas nécessairement simplement "trié" par ordre alphabétique)

De même, je cherche comment insérer un nœud de niveau "volume" qui n'est pas actuellement présent, car je crée de nouveaux hachages anonymes à insérer dans children à chaque couche du foreach boucle. Cela semble un peu maladroit, mais ce que je pense est:

  • Extraire une liste de volumes avec get_xpath("//volume") et uniqueifiez-le.
  • Soit itérer per volume trouver des sous-nœuds qui correspondent (Y a-t-il un xpath expression pour spécifier une valeur enfant?)
  • Ou créez un hachage "de mise en scène" de hachages que je "fusionne" dans children dans le JSON.

Quelqu'un a-t-il de meilleures suggestions?

Je peux assez facilement créer un hachage de la structure souhaitée, par ex.

$stuff{$site}{$server}{$volume}{$qtree} = $size;

Mais il faudrait ensuite le transformer en JSON approprié (ce qui, je suppose, pourrait être une meilleure approche dans l'ensemble).

Réponses:

1 pour la réponse № 1

y a-t-il un moyen d'appliquer une commande dans la sortie JSON?

Ouais, utilisez un tableau au lieu d'un objet. Les objets JSON ne sont pas ordonnés.

Un objet est un ensemble non ordonné de paires nom / valeur.

Mais il semble que vous utilisez déjà des tableaux pour vos listes.

Peut-être voulez-vous pouvoir effectuer des différences, auquel cas JSON.pm fournit un moyen grossier de spécifier des clés sous la forme de sort_by. Utile si vous souhaitez effectuer des diffs.


0 pour la réponse № 2

Si vous souhaitez simplement "appliquer" un tri par clé de hachage, vous pouvez utiliser la fonction "canonique", comme indiqué également ici.