Преобразование плоского файла в XML с использованием XSLT-подобной технологии - PullRequest
1 голос
/ 24 ноября 2008

Я разрабатываю систему, которая получает данные от ряда партнеров в виде файлов CSV. Файлы могут отличаться по количеству и порядку столбцов. По большей части я хочу выбрать подмножество столбцов, возможно, изменить их порядок и передать их анализатору. Очевидно, я бы предпочел иметь возможность преобразовывать входящие данные в некоторый канонический формат, чтобы сделать синтаксический анализатор максимально простым.

В идеале я хотел бы иметь возможность генерировать преобразование для каждого входящего формата данных с использованием некоторого графического инструмента и сохранять преобразование в виде документа в базе данных или на диске. После получения данных я применил бы правильное преобразование (не говоря уже о том, как определить правильное преобразование), чтобы получить документ XML в каноническом формате. Если бы входящие файлы содержали XML, я бы просто создал документ XSLT для каждого формата и был бы в пути.

Я использовал расширения BizTalk для плоских файлов XSLT (или как они там называются) для чего-то похожего в прошлом, но я не хочу хлопот BizTalk (и я не могу себе это позволить) в этом проекте.

Кто-нибудь знает, существуют ли альтернативные технологии и / или расширения XSLT, которые позволили бы мне элегантно достичь своей цели?

Я разрабатываю свое приложение на C # для .NET 3.5 SP1 (поэтому предпочел бы технологии, поддерживаемые .NET).

Ответы [ 8 ]

1 голос
/ 25 ноября 2008

XSLT предоставляет новые функции, которые упрощают анализ файлов, отличных от XML.

Эндрю Уэлч опубликовал пример XSLT 2.0, который преобразует CSV в XML

0 голосов
/ 30 июля 2010

это проанализирует вывод команды linux ip route list. Это именно то, что я лежал вокруг.

вы должны обернуть вывод от запятой в элемент с именем 'output', и таблица стилей возьмет его оттуда. Настоящим ключом здесь является команда tokenize в спецификации xpath 2.0. Я не знаю, как ты мог сделать это до этого. Также это не делает ни одного корневого элемента, так как это было не то, для чего я нуждался. В вашем случае вместо разделения на пробел, Id spli на ','

<?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>

0 голосов
/ 07 октября 2009

Ознакомьтесь с этой статьей о реализации XmlReader, которая обрабатывает ввод не-XML. Это не очень сложная задача, и как только она заработает, вам не нужно использовать XSLT-подобную технологию, вы можете просто использовать XSLT.

0 голосов
/ 06 октября 2009

Вы можете попробовать LINQ to CSV. Есть одно предложение от Эрика Уайта от Microsoft и другое от Мэтта Пердека . Другие там ...

0 голосов
/ 05 октября 2009

Я нашел 2 возможных решения, когда смотрел в похожее пространство проблем.

Progress Software имеет набор инструментов и API (.Net), которые при использовании в сочетании с файлами .conv (конвертер плоских в XML), созданными в их инструменте Stylus Studio, позволяют преобразовывать любой предварительно определенный формат плоских файлов в XML во время выполнения. Больше информации здесь: http://www.datadirect.com/developer/data-integration/tutorials/converter-sample-code/index.ssp

Кроме того, существует формат XML, называемый XFLAT, который позволяет описывать плоские файлы в различных форматах, с разделителями, фиксированной шириной и т. Д. Есть Java-программа, которая преобразует плоские файлы, если вы предоставили описание XFLAT в XML, чтобы вы могли продолжить стандартное преобразование XML в XML XSLT. Более подробную информацию можно найти здесь: http://www.unidex.com/overview.htm

Я никогда не использовал ни один из этих инструментов, но нашел их при исследовании аналогичной проблемы.

0 голосов
/ 17 февраля 2009

IIRC кто-то создал библиотеку «LINQ to CSV», которая может быть отправной точкой для создания промежуточного XML (в памяти) в качестве входных данных для преобразования.

Нашел здесь .

0 голосов
/ 24 ноября 2008

Вы также можете взглянуть на MapForce Альтовы

0 голосов
/ 24 ноября 2008

Я думаю, вам нужно что-то вроде этого (извините, не поддерживается .NET, но код очень прост)

http://csv2xml.sourceforge.net

...