2008-11-24 37 views
1

我正在設計一個系統,它以CSV文件的形式從多個合作伙伴接收數據。這些文件的列數和排序可能不同。大多數情況下,我會選擇列的一個子集,也許會重新排列它們,並將它們交給解析器。我顯然希望能夠將傳入的數據轉換爲一些規範格式,以便儘可能簡化解析器。使用類似XSLT的技術將平面文件轉換爲XML

理想情況下,我希望能夠使用某些圖形工具爲每個傳入數據格式生成轉換,並將轉換作爲文檔存儲在數據庫或磁盤中。在接收數據時,我會應用正確的轉換(不必介意我如何確定正確的轉換)以獲得規範格式的XML文檔。如果傳入的文件包含XML,那麼我只是爲每種格式創建了一個XSLT文檔,並且一直在我的路上。

我已經使用BizTalk的平面文件XSLT擴展(或任何他們被稱爲)在過去類似的東西,但我不想在這個項目上的BizTalk(我也買不起)的麻煩。

有誰知道是否有替代技術和/或XSLT擴展,這將使我能夠以優雅的方式實現我的目標?

我正在C#中開發我的應用程序在.NET 3.5 SP1(因此會更喜歡.NET支持的技術)。

回答

-1

您還可以看看altova's MapForce

+0

Altova的MapForce還希望生成的代碼從一個平面文件要到一個XML文件中。它不完全是用XSLT來完成的。 – Stimy 2009-09-30 19:53:29

0

IIRC有人創造了一個「LINQ到CSV」庫,可能是一個起點,創造中間XML(內存)作爲輸入到變換。

發現它here

0

在研究類似的問題空間時,我找到了2個潛在的解決方案。

Progress軟件有一套工具和API(.Net),當與Stylus Studio工具中創建的.conv(平面到XML轉換器)文件結合使用時,可以轉換任何預定義的平面文件格式在運行時轉換爲XML。更多的信息在這裏:http://www.datadirect.com/developer/data-integration/tutorials/converter-sample-code/index.ssp

此外,還有一種稱爲XFLAT的XML格式,它允許描述各種格式的平面文件,分隔符,固定寬度等......有一個java程序可以將平面文件,您已將XFLAT描述提交到XML中,以便繼續進行標準的XML到XML XSLT轉換。更多細節可以在這裏找到:http://www.unidex.com/overview.htm

我從來沒有真正使用這些工具,但在研究類似問題時發現它們。

0

檢出this article實施處理非XML輸入的XmlReader。這不是一件非常困難的任務,一旦你得到它的工作,你不需要使用類似XSLT的技術,你可以使用XSLT。

0

這將解析來自linux ip route list命令的輸出。這正是我放置的東西。

您必須將comman的輸出封裝在名爲'output'的元素中,並且樣式表將從中取出它。這裏真正的關鍵是xpath 2.0規範中的tokenize命令。我不知道你在這之前如何做到這一點。此外,這並不是一個單一的根元素,因爲這不是我所需要的。在你的情況,而不是劈裂空間,標識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>