2013-09-24 2 views
2

J'ai besoin de générer un fichier XML. C'est facile-peasy en C#. Le problème (en dehors de la requête de base de données lente [problème séparé]) est que le fichier de sortie atteint facilement 2 Go. En plus de cela, le XML de sortie n'est pas dans un format qui peut facilement être fait en SQL. Chaque élément parent regroupe des éléments dans ses enfants et conserve un identifiant unique séquentiel qui couvre le fichier. Exemple:Génération de fichiers XML très importante

<level1Element> 
    <recordIdentifier>1</recordIdentifier> 
    <aggregateOfLevel2Children>11</aggregateOfL2Children> 
    <level2Children> 
     <level2Element> 
     <recordIdentifier>2</recordIdentifier> 
      <aggregateOfLevel3Children>92929</aggregateOfLevel3Children> 
      <level3Children> 
       <level3Element> 
        <recordIdentifier>3</recordIdentifier> 
        <level3Data>a</level3Data> 
       </level3Element> 
       <level3Element> 
        <recordIdentifier>4</recordIdentifier> 
        <level3Data>b</level3Data> 
       </level3Element> 
      </level3Children> 
     </level2Element> 
     <level2Element> 
     <recordIdentifier>5</recordIdentifier> 
      <aggregateOfLevel3Children>92929</aggregateOfLevel3Children> 
      <level3Children> 
       <level3Element> 
        <recordIdentifier>6</recordIdentifier> 
        <level3Data>h</level3Data> 
       </level3Element> 
       <level3Element> 
        <recordIdentifier>7</recordIdentifier> 
        <level3Data>e</level3Data> 
       </level3Element> 
      </level3Children> 
     </level2Element> 
    </level2Children> 
</level1Element> 

Le schéma utilisé se fait jusqu'à cinq niveaux. Par souci de concision, j'inclus seulement 3. Je ne contrôle pas ce schéma, je ne peux pas non plus demander de changements.

Il est simple, même trivial de regrouper toutes ces données dans des objets et de les sérialiser en XML en fonction de ce schéma. Mais lorsque vous manipulez de telles quantités de données, des exceptions d'insuffisance de mémoire se produisent lors de l'utilisation de cette stratégie. La stratégie qui fonctionne pour moi est la suivante: Je remplis une collection d'entités via un ObjectContext qui rencontre une vue dans une base de données SQL Server (une base de données indexée de manière très inefficace). Je grouperai cette collection puis je ferai une itération, puis je grouperai le niveau suivant puis je ferai itération jusqu'à ce que j'arrive à l'élément de plus haut niveau. J'organise ensuite les données en objets qui reflètent le schéma (en fait, juste le mappage) et en définissant le recordIdentifier séquentiel (j'ai envisagé de le faire en SQL, mais le nombre de jointures ou CTE imbriquées serait ridicule compte tenu du fait que l'identifiant couvre les éléments d'en-tête dans les éléments enfants). J'écris un élément de niveau supérieur (disons le level2Element) avec ses enfants dans le fichier de sortie. Une fois que j'ai fini d'écrire à ce niveau, je passe au groupe parent et j'insère l'en-tête avec les données agrégées et son identifiant.

Quelqu'un a-t-il des idées concernant une meilleure façon de produire un tel fichier XML?

+4

Vous voulez savoir comment * le sortir *? Si vous utilisez un ['XMLTextWriter'] (http://msdn.microsoft.com/en-us/library/system.xml.xmltextwriter.aspx) sur une machine raisonnablement moderne, la taille du fichier ne doit être limitée que par: la quantité d'espace disque disponible. –

+0

S'il vous plaît montrer ce que vous avez essayé. Il existe plusieurs façons d'écrire une sortie XML dans un fichier. –

+0

Mai [la poste] (http://stackoverflow.com/questions/16432916/best-approach-to-write-huge-sql-dataset-into-xml-file/16433436#16433436) peut vous aider. –

Répondre

1

Pour autant que je comprends votre question, votre problème n'est pas avec l'espace de stockage limité par exemple HDD. Vous avez des difficultés à conserver un grand objet XDocument en mémoire, c'est-à-dire RAM. Pour faire face à cela, vous pouvez ignorer faire un tel objet énorme. Pour chaque élément recovrdIdentifier, vous pouvez appeler .ToString() et obtenir une chaîne. Maintenant, ajoutez simplement ces chaînes à un fichier. Mettez la déclaration et la balise racine dans ce fichier et vous avez terminé.