Pregunta

Estoy diseñando un sistema que recibe datos de varios socios en forma de archivos CSV. Los archivos pueden diferir en el número y el orden de las columnas. En su mayor parte, querré elegir un subconjunto de las columnas, tal vez reordenarlas y entregarlas a un analizador. Obviamente preferiría poder transformar los datos entrantes en algún formato canónico para que el analizador sea lo más simple posible.

Idealmente, me gustaría poder generar una transformación para cada formato de datos entrantes usando alguna herramienta gráfica y almacenar la transformación como un documento en una base de datos o en un disco. Al recibir los datos, aplicaría la transformación correcta (no importa cómo determine la transformación correcta) para obtener un documento XML en formato canónico. Si los archivos entrantes hubieran contenido XML, simplemente habría creado un documento XSLT para cada formato y estaría en camino.

He usado las Extensiones XSLT de archivos planos de BizTalk (o como se llamen) para algo similar en el pasado, pero no quiero la molestia de BizTalk (y tampoco me lo puedo permitir) en este proyecto.

¿Alguien sabe si hay tecnologías alternativas y / o extensiones XSLT que me permitan lograr mi objetivo de una manera elegante?

Estoy desarrollando mi aplicación en C # en .NET 3.5 SP1 (por lo tanto, preferiría tecnologías compatibles con .NET).

¿Fue útil?

Solución

XSLT proporciona nuevas funciones que facilitan el análisis de archivos que no son XML.

Andrew Welch publicó un XSLT 2.0 ejemplo que convierte CSV en XML

Otros consejos

Creo que necesita algo como esto (lo siento, no es compatible con .NET pero el código es muy simple)

http://csv2xml.sourceforge.net

IIRC alguien ha creado un "LINQ to CSV" biblioteca que podría ser un punto de partida para crear el XML intermedio (en memoria) como entrada en la transformación.

Lo encontré aquí .

Puede probar LINQ to CSV. Hay una oferta de Eric White y otro de Matt Perdeck . Otros están por ahí ...

He encontrado 2 posibles soluciones cuando busco en un espacio problemático similar.

Progress Software tiene un conjunto de herramientas y API (.Net), que cuando se usa junto con archivos .conv (convertidor de plano a XML) creados en su herramienta Stylus Studio permite la transformación de cualquier formato de archivo plano predefinido en XML en tiempo de ejecución. Más información aquí: http: // www. datadirect.com/developer/data-integration/tutorials/converter-sample-code/index.ssp ??

Además, hay un formato XML llamado XFLAT que permite la descripción de archivos planos en una variedad de formatos, delimitados, de ancho fijo, etc. Hay un programa java que convertirá archivos planos, donde ha proporcionado la descripción de XFLAT en XML para que pueda continuar con una transformación estándar XML a XML XSLT. Se pueden encontrar más detalles aquí: http://www.unidex.com/overview.htm

Nunca he usado ninguna de estas herramientas, pero las encontré al investigar un problema similar.

Consulte este artículo sobre la implementación de un XmlReader que procesa la entrada no XML. No es una tarea terriblemente difícil, y una vez que lo tiene funcionando no necesita usar una tecnología similar a XSLT, simplemente puede usar XSLT.

esto analizará la salida del comando linux ip route list. Es justo lo que tenía por ahí.

debe envolver la salida del comando en un elemento llamado 'salida' y la hoja de estilo lo tomará desde allí. La clave real aquí es el comando tokenize en la especificación xpath 2.0. No sé cómo podrías hacer esto antes de eso. Además, esto no hace un solo elemento raíz, ya que no era para lo que lo necesitaba. En su caso, en lugar de dividir en el espacio, Id spli en 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>

También puede consultar MapForce de altova

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top