2011-10-31 5 views
1

Je demandais comment puis-je diviser une grande sortie XML de NokogiriXML de Split grand en plusieurs fichiers

Par exemple, j'ai rempli Nokogiri::XML avec des données et maintenant je veux stocker toutes ces données dans des fichiers séparés, chaque pas plus grand que 10MB.

Modifier de commentaire: Nous ne voulons pas diviser au milieu de l'étiquette, nous voulons répliquer en-tête xml dans chaque fichier, il doit y avoir quelque chose dans les méthodes de Nokogiri.

+2

Cela semble être une bonne question, mais vous devez être plus explicite dans vos exigences, de préférence avec l'entrée et la sortie d'échantillons. Si vous avez '

18 Mo de texte

' quel devrait être le résultat? Que diriez-vous de '6MB6MB6MB'? Que diriez-vous de '4Mo4Mo 4Mo'? – Phrogz

+0

Ce n'est pas quelque chose que Nokogiri devrait savoir faire; Nokogiri génère du XML que vous lui dites de créer. En tant que développeur, vous devez savoir combien de données vous générez, puis prendre des mesures pour diviser ces données en blocs gérables avant de générer le fichier XML. Cela est vrai que vous soyez en train de créer du XML avec Nokogiri, ou de générer des messages YAML, JSON ou e-mail avec leurs générateurs appropriés. –

+0

Encore un cas particulièrement pathologique: Que devrait être la sortie pour "" et ainsi de suite jusqu'à ce que vous ayez plusieurs mégaoctets de valeur d'attributs? – Phrogz

Répondre

1

Disons que vous avez un xml:

xml = '<foo><child num="1"/><child num="2"/><child num="3"/></foo>' 
doc = Nokogiri::XML(xml) 

Et vous voulez briser les gammes de nœuds enfants et de les enregistrer séparément sans perdre la hiérarchie. Vous pourriez faire quelque chose comme:

[0..0, 1..1, 2..2].each do |range| 
    c = doc.clone 
    (c.xpath('/foo/child') - c.xpath('/foo/child')[range]).remove #remove nodes not in range 
    File.open("#{range.first}.xml", 'w') {|f| f.write(c.to_s) } 
end 
+0

génial! puis-je le faire plus simplement? Par exemple, objet nokogiri (sitemap) contient un grand nombre de * Je dois faire quelque chose comme ** chaque ** sur cet objet, à chaque exécution, nous comptons le nombre d'octets – com

0

Que diriez-vous à l'aide de ce simple extrait:

def split_by_size(text, size = 10 * 1024 * 1024) 
    text.scan /.{1, #{size}}/ 
end 

split_by_size("12345" * 2, 3) # => ["123", "451", "234", "5"] 

Vous pouvez utiliser ce tableau de morceaux pour les enregistrer dans des fichiers séparés.

+0

bien, mais ne convient pas pour XML, nous ne voulons pas diviser au milieu de la balise, nous voulons répliquer xml en-tête dans chaque fichier, il doit y avoir quelque chose dans les méthodes de nokogiri – com

+1

Cela casserait sérieusement un fichier XML. –

Questions connexes