2010-11-10 66 views
0

我有一些XML從表下面的形式儲存列信息和行數據:XSL轉換爲表數據

<?xml version="1.0" encoding="utf-8"?> 
<table> 
    <columns> 
    <column id="1"> 
     <name>Date</name> 
     <type>Date</type> 
    </column> 
    <column id="2"> 
     <name>Name</name> 
     <type>String</type> 
    </column> 
    </columns> 
    <rows> 
    <row id="1"> 
     <columns> 
     <column id="1"> 
      <name>Date</name> 
      <value>1-Dec-2010</value> 
      <localDate>1-Dec-2010 00:00:00 GMT</localDate> 
     </column> 
     <column id="2"> 
      <name>Name</name> 
      <value>Jim</value> 
     </column> 
     </columns> 
    </row> 
    <row id="2"> 
     <columns> 
     <column id="1"> 
      <name>Date</name> 
      <value>2-Dec-2010</value> 
      <localDate>2-Dec-2010 00:00:00 GMT</localDate> 
     </column> 
     <column id="2"> 
      <name>Name</name> 
      <value>Jane</value> 
     </column> 
     </columns> 
    </row> 
    </rows> 
</table> 

注意:這是我的XML的削減版本。我有更多的行,並在每列上存儲更多信息。

是否可以應用XSL轉換,該轉換將遍歷xml中的每一行並輸出每個列值。如果列的類型是DateTime(如列信息中指定的那樣),我想輸出localDate文本值,否則我將只輸出文本值。

我可以做一些XSL,但我不確定如何檢查文檔的不同部分,這些部分本質上將從tableModel/rows/row/columns/column映射到tableModel/columns /列。

我基本上輸出爲CSV。我有代碼來追加每個/ tableModel/rows/row/columns/column xml的列信息,但我認爲這是不必要的,並且它使Netbeans/Visual Studio處理的xml太大(大約7MB)。

我想獲得的輸出是:

Date,Name 
1-Dec-2010 00:00:00 GMT,Jim 
2-Dec-2010 00:00:00 GMT,Jane 

非常感謝,

Andez

回答

2

好以下生產所描述的輸出作爲輸入樣本

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="1.0"> 

    <xsl:param name="sep" select="','"/> 
    <xsl:param name="lf" select="'&#10;'"/> 

    <xsl:output method="text"/> 

    <xsl:template match="/"> 
    <xsl:apply-templates select="table/columns/column/name"/> 
    <xsl:value-of select="$lf"/> 
    <xsl:apply-templates select="table/rows/row"/> 
    </xsl:template> 

    <xsl:template match="column/name"> 
    <xsl:value-of select="."/> 
    <xsl:if test="position() != last()"> 
     <xsl:value-of select="$sep"/> 
    </xsl:if> 
    </xsl:template> 

    <xsl:template match="rows/row"> 
    <xsl:apply-templates select="columns/column"/> 
    <xsl:value-of select="$lf"/> 
    </xsl:template> 

    <xsl:template match="row/columns/column[not(localDate)]"> 
    <xsl:value-of select="value"/> 
    <xsl:if test="position() != last()"> 
     <xsl:value-of select="$sep"/> 
    </xsl:if> 
    </xsl:template> 

    <xsl:template match="row/columns/column[localDate]"> 
    <xsl:value-of select="localDate"/> 
    <xsl:if test="position() != last()"> 
     <xsl:value-of select="$sep"/> 
    </xsl:if> 
    </xsl:template> 

</xsl:stylesheet> 

但它不會查看相應的列類型,它只是輸出localDate元素如果存在。這足夠嗎? 還請說明您是否可以使用XSLT 2.0(由AltovaXML Tools或Saxon 9實現),這樣可以使這些內容更容易。

[編輯]我想用在匹配模式的關鍵,雖然未在XSLT 1.0允許的,但現在看來,這工作這麼以下是更好地執行你的要求:

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="1.0"> 

    <xsl:param name="sep" select="','"/> 
    <xsl:param name="lf" select="'&#10;'"/> 

    <xsl:key name="k1" match="table/columns/column" use="@id"/> 

    <xsl:output method="text"/> 

    <xsl:template match="/"> 
    <xsl:apply-templates select="table/columns/column/name"/> 
    <xsl:value-of select="$lf"/> 
    <xsl:apply-templates select="table/rows/row"/> 
    </xsl:template> 

    <xsl:template match="column/name"> 
    <xsl:value-of select="."/> 
    <xsl:if test="position() != last()"> 
     <xsl:value-of select="$sep"/> 
    </xsl:if> 
    </xsl:template> 

    <xsl:template match="rows/row"> 
    <xsl:apply-templates select="columns/column"/> 
    <xsl:value-of select="$lf"/> 
    </xsl:template> 

    <xsl:template match="row/columns/column[not(key('k1', @id)/type = 'Date')]"> 
    <xsl:value-of select="value"/> 
    <xsl:if test="position() != last()"> 
     <xsl:value-of select="$sep"/> 
    </xsl:if> 
    </xsl:template> 

    <xsl:template match="row/columns/column[key('k1', @id)/type = 'Date']"> 
    <xsl:value-of select="localDate"/> 
    <xsl:if test="position() != last()"> 
     <xsl:value-of select="$sep"/> 
    </xsl:if> 
    </xsl:template> 

</xsl:stylesheet> 
+0

馬丁你好。感謝那。我目前在M $ Visual Studio 2008中編寫我的XSL,儘管我們正在編寫代碼以在Netbeans 6.9.1下生成Java中的變換。我討厭Netbeans中的XML編輯器。 – Andez 2010-11-10 15:14:48

+0

理想情況下,我想鏈接到行中的列,因爲還有其他信息,我將檢查如格式等。 – Andez 2010-11-10 15:15:29

+0

與Java一樣,您可以切換到Saxon 9和XSLT 2.0作爲XSLT處理器。但請參閱我的編輯,它顯示瞭如何使用鍵來查找引用列,並且它適用於XSLT 1.0。 – 2010-11-10 15:19:19

0

這少冗長,但也許......深奧的樣式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text"/> 
    <xsl:key name="kDataType" match="type" use="../@id"/> 
    <xsl:template match="value|table/*/*/name"> 
     <xsl:variable name="vIsDateType" 
         select="key('kDataType',../@id)='Date'"/> 
     <xsl:value-of 
      select="concat(substring(',', 
             1 div boolean(../preceding-sibling::*)), 
          self::name, 
          self::value[not($vIsDateType)], 
          ../localDate[$vIsDateType], 
          substring('&#xA;', 
             1 div not(../following-sibling::*)))"/> 
    </xsl:template> 
    <xsl:template match="text()"/> 
</xsl:stylesheet> 

輸出:

Date,Name 
1-Dec-2010 00:00:00 GMT,Jim 
2-Dec-2010 00:00:00 GMT,Jane