Domanda

Sto progettando un sistema che sta ricevendo dati da un numero di partner sotto forma di file CSV. I file possono differire nel numero e nell'ordine delle colonne. Per la maggior parte, vorrò scegliere un sottoinsieme delle colonne, magari riordinarle e consegnarle a un parser. Preferirei ovviamente essere in grado di trasformare i dati in arrivo in un formato canonico in modo da rendere il parser il più semplice possibile.

Idealmente, vorrei essere in grado di generare una trasformazione per ogni formato di dati in entrata utilizzando uno strumento grafico e archiviare la trasformazione come documento in un database o su disco. Alla ricezione dei dati, applicherei la trasformazione corretta (non importa come determino la trasformazione corretta) per ottenere un documento XML in un formato canonico. Se i file in arrivo contenessero XML avrei appena creato un documento XSLT per ogni formato e sarei stato sulla mia strada.

Ho usato le estensioni XSLT per file flat di BizTalk (o come si chiamano) per qualcosa di simile in passato, ma non voglio il fastidio di BizTalk (e non posso permettermelo) in questo progetto.

Qualcuno sa se ci sono tecnologie alternative e / o estensioni XSLT che mi consentirebbero di raggiungere il mio obiettivo in modo elegante?

Sto sviluppando la mia app in C # su .NET 3.5 SP1 (quindi preferirei le tecnologie supportate da .NET).

È stato utile?

Soluzione

XSLT offre nuove funzionalità che semplificano l'analisi dei file non XML.

Andrew Welch ha registrato un XSLT 2.0 esempio che converte CSV in XML

Altri suggerimenti

Credo che avete bisogno di qualcosa di simile (mi dispiace, non supportata da .NET, ma il codice è molto semplice)

http://csv2xml.sourceforge.net

IIRC qualcuno ha creato un "LINQ to CSV" libreria che potrebbe essere un punto di partenza per creare l'XML intermedio (in memoria) come input nella trasformazione.

Trovato qui .

Potresti provare LINQ to CSV. C'è un'offerta da Eric White e un altro da Matt Perdeck . Altri sono là fuori ...

Ho trovato 2 potenziali soluzioni osservando uno spazio problematico simile.

Progress Software ha una serie di strumenti e API (.Net) che, se usati in combinazione con file .conv (convertitore da flat a XML) creati nel loro strumento Stylus Studio, consentono la trasformazione di qualsiasi formato di file flat predefinito in XML in fase di esecuzione. Maggiori informazioni qui: http: // www. datadirect.com/developer/data-integration/tutorials/converter-sample-code/index.ssp ??

Inoltre esiste un formato XML chiamato XFLAT che consente la descrizione di file flat in una varietà di formati, delimitati, a larghezza fissa ecc ... Esiste un programma java che converte file flat, dove hai provato la descrizione XFLAT in XML in modo da poter continuare con una trasformazione XSLT da XML a XML standard. Maggiori dettagli sono disponibili qui: http://www.unidex.com/overview.htm

Non ho mai usato nessuno di questi strumenti, ma li ho trovati durante la ricerca di un problema simile.

Leggi questo articolo sull'implementazione di un XmlReader che elabora input non XML. Non è un compito tremendamente difficile e una volta che lo fai funzionare non è necessario utilizzare una tecnologia simile a XSLT, puoi semplicemente usare XSLT.

questo analizzerà l'output dal comando dell'elenco delle rotte ip di linux. È proprio quello che avevo in giro.

devi avvolgere l'output del comando in un elemento chiamato 'output' e il foglio di stile lo prenderà da lì. La vera chiave qui è il comando tokenize nella specifica xpath 2.0. Non so come potresti farlo prima. Inoltre, questo non costituisce un singolo elemento radice, poiché non era quello per cui avevo bisogno. Nel tuo caso, invece di dividere lo spazio, Id spli su 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>

Puoi anche dare un'occhiata a MapForce di altova

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top