2010-01-29 61 views
0

我有這個XML文件,我想創建一個XSL文件將其轉換爲Excel。每行應代表一個標誌。這些列將是關鍵屬性,如顏色,編號,描述以及其他徽標的任何其他關鍵字。使用XSLT創建Excel(SpeadsheetML)輸出

<Top> 
    <logo> 
    <field key="id">172-32-1176</field> 
    <field key="color">Blue</field> 
    <field key="description"><p>Short Description</p></field> 
    <field key="startdate">408 496-7223</field> 
    </logo> 
    <logo> 
    <field key="id">111-111-111</field> 
    <field key="color">Red</field> 
    </logo> 
    <!-- ... -->  
</Top> 

XSL文件是這樣的:

<xsl:stylesheet 
    version="1.0" 
    xmlns="urn:schemas-microsoft-com:office:spreadsheet" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
    xmlns:user="urn:my-scripts" 
    xmlns:o="urn:schemas-microsoft-com:office:office" 
    xmlns:x="urn:schemas-microsoft-com:office:excel" 
    xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" 
> 

    <xsl:template match="/"> 
    <Workbook 
     xmlns="urn:schemas-microsoft-com:office:spreadsheet" 
     xmlns:o="urn:schemas-microsoft-com:office:office" 
     xmlns:x="urn:schemas-microsoft-com:office:excel" 
     xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" 
     xmlns:html="http://www.w3.org/TR/REC-html40" 
    > 
     <xsl:apply-templates/> 
    </Workbook> 
    </xsl:template> 

    <xsl:template match="/*"> 
    <Worksheet> 
     <xsl:attribute name="ss:Name"> 
     <xsl:value-of> select="local-name(/*)"/> 
     </xsl:attribute> 
     <Table x:FullColumns="1" x:FullRows="1"> 
     <Row> 
      <xsl:for-each select="*/*"> 
      <Cell> 
       <Data ss:Type="String"> 
       <xsl:value-of select="@key"/> 
       </Data> 
      </Cell> 
      </xsl:for-each> 
     </Row> 
     <xsl:apply-templates/> 
     </Table> 
    </Worksheet> 
    </xsl:template> 

    <xsl:template match="/*/*"> 
    <Row> 
     <xsl:apply-templates/> 
    </Row> 
    </xsl:template> 

    <xsl:template match="/*/*/*"> 
    <Cell> 
     <Data ss:Type="String"> 
     <xsl:value-of select="."/> 
     </Data> 
    </Cell> 
    <!-- <xsl:apply-templates/> --> 
    </xsl:template> 
</xsl:stylesheet> 

但數據放置不正確的列名和列名以下的重複。如何才能做到這一點? 這些列可以以任何順序排列,並且在Excel中第二行的列stardate也應該爲空。同樣的更多。

回答

2

你非常接近。嘗試在模板匹配方面更具體 - 當您可以說template match="field"時,不要說template match"/*/*/*"

除此之外,這是你的方法,只是略作修改:

<xsl:stylesheet 
    version="1.0" 
    xmlns="urn:schemas-microsoft-com:office:spreadsheet" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
    xmlns:user="urn:my-scripts" 
    xmlns:o="urn:schemas-microsoft-com:office:office" 
    xmlns:x="urn:schemas-microsoft-com:office:excel" 
    xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" 
> 
    <xsl:output method="xml" encoding="utf-8" indent="yes" /> 

    <xsl:template match="/"> 
    <Workbook 
     xmlns="urn:schemas-microsoft-com:office:spreadsheet" 
     xmlns:o="urn:schemas-microsoft-com:office:office" 
     xmlns:x="urn:schemas-microsoft-com:office:excel" 
     xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" 
     xmlns:html="http://www.w3.org/TR/REC-html40" 
    > 
     <xsl:apply-templates select="Top" /> 
    </Workbook> 
    </xsl:template> 

    <xsl:template match="Top"> 
    <Worksheet ss:Name="{local-name()}"> 
     <Table x:FullColumns="1" x:FullRows="1"> 
     <Row> 
      <!-- header row, made from the first logo --> 
      <xsl:apply-templates select="logo[1]/field/@key" /> 
     </Row> 
     <xsl:apply-templates select="logo" /> 
     </Table> 
    </Worksheet> 
    </xsl:template> 

    <!-- a <logo> will turn into a <Row> --> 
    <xsl:template match="logo"> 
    <Row> 
     <xsl:apply-templates select="field" /> 
    </Row> 
    </xsl:template> 

    <!-- convenience: <field> and @key both turn into a <Cell> --> 
    <xsl:template match="field | field/@key"> 
    <Cell> 
     <Data ss:Type="String"> 
     <xsl:value-of select="."/> 
     </Data> 
    </Cell> 
    </xsl:template> 

</xsl:stylesheet> 

你的「重複列名」的問題根源在此表達:

<xsl:for-each select="*/*"> 

在你的背景下,這一選擇文檔中的任何第三級元素(字面上全部爲<logo>s中的所有<field>節點),並使它們中的標題行出現。我用

<xsl:apply-templates select="logo[1]/field/@key" /> 

這使得標題行出只有第一<logo>代替它。

如果需要某個列順序(文檔順序除外)或不是所有<field>節點與所有<logo> s的順序相同,則事情會變得更加複雜。告訴我你是否需要這個。

+0

這正是我所面臨的問題。字段的順序不同,並且並非所有字段都在第一個中。所以我需要擁有所有不同的專欄。 – Learner

+0

@Learner:這不是不可能的,但解決方案取決於你是否想要使用某種自然順序(例如,按鍵按字母順序排序)或者你定義的任意順序。前者較少,後者較爲複雜。我可以爲兩種偏好創建解決方案。 – Tomalak