2009-11-03 4 views
1

J'ai un tableau multidimensionnel que je voudrais utiliser pour la construction d'une sortie xml.Array pour XML - Rails

Le réseau stocke une importation de CSV. Où les personnes [0] [...] sont les noms de colonne qui deviendront les balises xml, et les personnes [...> 0] [...] sont les valeurs.

For instance, array contains: 
people[0][0] => first-name 
people[0][1] => last-name 
people[1][0] => Bob 
people[1][1] => Dylan 
people[2][0] => Sam 
people[2][1] => Shepard 

XML needs to be: 
<person> 
    <first-name>Bob</first-name> 
    <last-name>Dylan</last-name> 
</person> 
<person> 
    <first-name>Sam</first-name> 
    <last-name>Shepard</last-name> 
</person> 

Toute aide est appréciée.

+2

Si c'est une importation, est-il une raison quelconque vous n'êtes pas importer à un hachage au lieu d'un tableau? Hash # to_xml rend les choses beaucoup plus faciles parce que vos clés sont correctement nommées. – bensie

Répondre

-1

Merci à tous ceux qui ont affiché. Voici la solution qui semble fonctionner le mieux pour mes besoins. J'espère que d'autres pourraient trouver cela utile.

Cette solution saisit un fichier csv url à distance, les stocke dans un tableau multidimensionnel, il exporte comme xml:

require 'rio' 
require 'fastercsv' 

url = 'http://remote-url.com/file.csv' 
people = FasterCSV.parse(rio(url).read) 

xml = '' 
1.upto(people.size-1) do |row_idx| 
    xml << " <record>\n" 
    people[0].each_with_index do |column, col_idx| 
    xml << " <#{column.parameterize}>#{people[row_idx][col_idx]}</#{column.parameterize}>\n" 
    end 
    xml << " </record>\n" 
end 

Il existe de meilleures solutions là-bas, en utilisant hash.to_xml aurait été super sauf que j'avais besoin de changer la ligne d'index csv pour paramétrer à utiliser comme une balise xml, mais ce code fonctionne donc je suis heureux.

7

Je suggère d'utiliser FasterCSV pour importer vos données et de le convertir en un tableau de hash. Cette to_xml façon devrait vous donner ce que vous voulez:

people = [] 
FasterCSV.foreach("yourfile.csv", :headers => true) do |row| 
people << row.to_hash 
end 
people.to_xml 
+0

Belle solution, +1 –

+0

Vous avez cette erreur: méthode non définie 'to_hash 'pour # Jeffrey

+0

Jeffery - le code ci-dessus fonctionnera si vous utilisez l'environnement Rails ou un script/console. Si vous utilisez juste l'interpréteur de base Ruby ou irb, cela vous donnera l'erreur ci-dessus. Vous devrez inclure des modules/bibliothèques pour le support xml si vous utilisez simplement Ruby/irb. – Phil

2

Il y a deux façons principales que je peux penser à y parvenir, un à l'aide d'un sérialiseur XML; la seconde en poussant la corde brute.

Voici un exemple de la seconde:

xml = '' 
1.upto(people.size-1) do |row_idx| 
    xml << "<person>\n" 
    people[0].each_with_index do |column, col_idx| 
    xml << " <#{column}>#{people[row_idx][col_idx]}</#{column}>\n" 
    end 
    xml << "</person>\n" 
end 

Une autre façon:

hash = {} 
hash['person'] = [] 
1.upto(people.size-1) do |row_idx| 
    row = {} 
    people[0].each_with_index do |column, col_idx| 
    row[column]=people[row_idx][col_idx] 
    end 
    hash['person'] << row 
end 
hash.to_xml 

Laissant cette réponse ici au cas où quelqu'un a besoin de convertir un tableau comme celui-ci qui ne sont pas venus d'un fichier CSV fichier (ou s'ils ne peuvent pas utiliser FasterCSV).

+0

fd - le second fonctionne très bien avec le tableau. est-il possible d'ajouter des personnes [0] [x] .parameterize au code? – Jeffrey

+0

En supposant que je comprenne bien, changez row [column] = ... en row [column.parameterize] = ... –

+0

Merci, ça marche. Bien que je m'éloigne de l'utilisation d'un hachage parce que l'ordre d'affichage est important ... à moins qu'il y ait un travail pour ça? L'application utilise des rails 2.3.4. – Jeffrey

1

L'utilisation Hash.to_xml est une bonne idée, en raison de son soutien dans les rails de base. C'est probablement le moyen le plus simple d'exporter des données de type Hash vers du XML simple. Dans la plupart des cas simples, des cas plus complexes nécessitent des outils plus complexes.