Transformation d'un fichier à plat en XML à l'aide d'une technologie semblable à XSLT

StackOverflow https://stackoverflow.com/questions/315074

Question

Je conçois un système qui reçoit des données de plusieurs partenaires sous forme de fichiers CSV. Les fichiers peuvent différer par le nombre et l'ordre des colonnes. Pour la plupart, je voudrai choisir un sous-ensemble des colonnes, peut-être les réorganiser et les remettre à un analyseur. Je préférerais évidemment pouvoir transformer les données entrantes en un format canonique afin de simplifier au maximum l'analyseur.

Idéalement, j'aimerais pouvoir générer une transformation pour chaque format de données entrant à l'aide d'un outil graphique et stocker la transformation sous forme de document dans une base de données ou sur un disque. À la réception des données, j'appliquerais la bonne transformation (peu importe comment je déterminerai la bonne transformation) pour obtenir un document XML au format canonique. Si les fichiers entrants contenaient du code XML, j’aurais simplement créé un document XSLT pour chaque format et l’aurais été.

J'ai utilisé les extensions XSLT de fichiers plats de BizTalk (ou le nom de leur nom) pour une application similaire dans le passé, mais je ne veux pas de problèmes avec BizTalk (et je ne peux pas me le permettre non plus) sur ce projet.

Est-ce que quelqu'un sait s'il existe des technologies alternatives et / ou des extensions XSLT qui me permettraient d'atteindre mon objectif de manière élégante?

Je développe mon application en C # sur .NET 3.5 SP1 (préférerais donc les technologies prises en charge par .NET).

Était-ce utile?

La solution

XSLT fournit de nouvelles fonctionnalités facilitant l'analyse de fichiers non XML.

Andrew Welch a publié un XSLT Exemple 2.0 qui convertit un fichier CSV en XML

Autres conseils

Je pense que vous avez besoin de quelque chose comme ça (désolé, pas supporté par .NET mais le code est très simple)

http://csv2xml.sourceforge.net

Un IIRC a créé un "LINQ to CSV". bibliothèque pouvant servir de point de départ pour créer le XML intermédiaire (en mémoire) en tant qu'entrée dans la transformation.

trouvé ici .

Vous pouvez essayer LINQ to CSV. Il y a une offre de Microsoft Eric White et une autre de Matt Perdeck . D'autres sont là-bas ...

J'ai trouvé deux solutions potentielles lors de la recherche dans un espace problématique similaire.

Progress Software dispose d’un ensemble d’outils et d’API (.Net) qui, utilisés avec les fichiers .conv (convertisseurs de formats plats en XML) créés dans leur outil Stylus Studio, permettent de transformer tout format de fichier plat prédéfini en fichier. XML au moment de l'exécution. Plus d'informations ici: http: // www. datadirect.com/developer/data-integration/tutorials/converter-sample-code/index.ssp ??

De plus, il existe un format XML appelé XFLAT qui permet la description de fichiers plats dans une variété de formats, délimités, à largeur fixe, etc. Il existe un programme java qui convertira les fichiers plats, pour lesquels vous avez fourni la description XFLAT en XML afin que vous puissiez continuer avec une transformation XSLT XML à XML standard. Plus de détails peuvent être trouvés ici: http://www.unidex.com/overview.htm

Je n'ai jamais utilisé aucun de ces outils, mais je les ai trouvés lors de la recherche d'un problème similaire.

Découvrez cet article sur la mise en œuvre d'un XmlReader qui traite les entrées non XML. Ce n'est pas une tâche terriblement difficile, et une fois que tout fonctionne, vous n'avez plus besoin d'utiliser une technologie semblable à XSLT, vous pouvez simplement utiliser XSLT.

Ceci analysera le résultat de la commande linux ip route list. C'est juste ce que je traînais.

vous devez envelopper la sortie du paramètre comman dans un élément appelé "output" et la feuille de style la prendra à partir de là. La vraie clé ici est la commande tokenize dans la spécification xpath 2.0. Je ne sais pas comment tu pourrais faire ça avant ça. De plus, cela ne fait pas un seul élément racine, car ce n’était pas ce dont j’avais besoin. Dans votre cas, au lieu de diviser sur l'espace, id spli sur un ','

<?xml version="1.0" encoding="UTF-8"?>

<xsl:output method="xml" indent="yes" />

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
</xsl:template>

<xsl:template match="//output">
    <!-- split things up for each new line -->
    <xsl:variable name="line" select="tokenize(.,'\n')"/>
    <xsl:for-each select="$line">                        
        <!-- split each line into peices based on space -->
        <xsl:variable name="split" select="tokenize(.,' +')"/>
        <xsl:if test="count($split) &gt; 1">
            <xsl:element name="route">                                        
                <xsl:for-each select="$split">
                    <xsl:choose>
                        <xsl:when test="position() = 1">
                            <xsl:attribute name="address" select="."/>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:variable name="index" select="position()"/>
                            <xsl:variable name="fieldName" select="."/>
                            <xsl:if test="$fieldName and position() mod 2 = 0">
                                <xsl:attribute name="{$fieldName}" select="$split[$index + 1]"/>
                            </xsl:if>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:for-each>
            </xsl:element>
        </xsl:if>
    </xsl:for-each>
</xsl:template>

Vous pouvez également consulter le logiciel MapForce d'altova

.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top