2012-02-29 68 views
1

我一直在努力想弄清楚如何使用XSLT轉換XML。主要目標是獲取XML源數據並根據月份數據重複/創建新行。比如當前每行有「X」個月的數據都是一行。我試圖解決這個問題,以便每行只包含一個月的數據。然後下一行將包含相同的標題信息,但包含原始源行的下一個月的數據。希望這是有道理的。我也在試圖找出如何在一行中配置月份列以觸發該月的數值的新值作爲目標XML中的新值,如我的示例中所示。任何建議將非常感激。XSLT如何將XML轉換爲新元素組和屬性

源碼:結果XML

<?xml version="1.0"?> 
<?xml-stylesheet type="txt/xsl" href="transform.xsl"?> 
<Report> 
<ReportData> 
<DataSet> 
<Row rowNum="1"> 
<Column name="Title 1"><Val xsi:type="xsd:string">Sample 1</Val></Column> 
<Column name="Title 2"><Val xsi:type="xsd:string">Sample 2</Val></Column> 
<Column name="Title 3"><Val xsi:type="xsd:string">Sample 3</Val></Column> 
<Column name="Title 4"><Val xsi:type="xsd:string">Sample 4</Val></Column> 
<Column name="Title 5"><Val xsi:type="xsd:string">160X600</Val></Column> 
<Column name="Title 6"><Val xsi:type="xsd:string" xsi:nil="true"></Val></Column> 
<Column name="Title 7"><Val xsi:type="xsd:integer">1325600</Val></Column> 
<Column name="MAR_Month_ID"><Val xsi:type="xsd:integer">3</Val></Column> 
<Column name="YEAR"><Val xsi:type="xsd:integer">2012</Val></Column> 
<Column name="MAR_Month_Total"><Val xsi:type="xsd:float">19.00</Val></Column> 
<Column name="MAR_Month_Total_B"><Val xsi:type="xsd:float">22.00</Val></Column> 
</Row> 
<Row rowNum="2"> 
<Column name="Title 1"><Val xsi:type="xsd:string">Sample 1</Val></Column> 
<Column name="Title 2"><Val xsi:type="xsd:string">Sample 2</Val></Column> 
<Column name="Title 3"><Val xsi:type="xsd:string">Sample 3</Val></Column> 
<Column name="Title 4"><Val xsi:type="xsd:string">Sample 4</Val></Column> 
<Column name="Title 5"><Val xsi:type="xsd:string">160X600</Val></Column> 
<Column name="Title 6"><Val xsi:type="xsd:string" xsi:nil="true"></Val></Column> 
<Column name="Title 7"><Val xsi:type="xsd:integer">1325600</Val></Column> 
<Column name="APR_Month_ID"><Val xsi:type="xsd:integer">4</Val></Column> 
<Column name="YEAR"><Val xsi:type="xsd:integer">2012</Val></Column> 
<Column name="APR_Month_Total"><Val xsi:type="xsd:float">18.00</Val></Column> 
<Column name="APR_Month_Total_B"><Val xsi:type="xsd:float">35.00</Val></Column> 
</Row> 
<Row rowNum="3"> 
<Column name="Title 1"><Val xsi:type="xsd:string">Sample 1</Val></Column> 
<Column name="Title 2"><Val xsi:type="xsd:string">Sample 2</Val></Column> 
<Column name="Title 3"><Val xsi:type="xsd:string">Sample 3</Val></Column> 
<Column name="Title 4"><Val xsi:type="xsd:string">Sample 4</Val></Column> 
<Column name="Title 5"><Val xsi:type="xsd:string">160X600</Val></Column> 
<Column name="Title 6"><Val xsi:type="xsd:string" xsi:nil="true"></Val></Column> 
<Column name="Title 7"><Val xsi:type="xsd:integer">1325600</Val></Column> 
<Column name="MAY_Month_ID"><Val xsi:type="xsd:integer">5</Val></Column> 
<Column name="YEAR"><Val xsi:type="xsd:integer">2012</Val></Column> 
<Column name="MAY_Month_Total"><Val xsi:type="xsd:float">25.00</Val></Column> 
<Column name="MAY_Month_Total_B"><Val xsi:type="xsd:float">15.00</Val></Column> 
</Row> 
<Row RowNum="4"> 
<Column name="Title 1"><Val xsi:type="xsd:string">Sample 5</Val></Column> 
<Column name="Title 2"><Val xsi:type="xsd:string">Sample 6</Val></Column> 
<Column name="Title 3"><Val xsi:type="xsd:string">Sample 7</Val></Column> 
<Column name="Title 4"><Val xsi:type="xsd:string">Sample 8</Val></Column> 
<Column name="Title 5"><Val xsi:type="xsd:string">250X600</Val></Column> 
<Column name="Title 6"><Val xsi:type="xsd:string" xsi:nil="true"></Val></Column> 
<Column name="Title 7"><Val xsi:type="xsd:integer">5600</Val></Column> 
<Column name="MAR_Month_ID"><Val xsi:type="xsd:integer">3</Val></Column> 
<Column name="YEAR"><Val xsi:type="xsd:integer">2012</Val></Column> 
<Column name="MAR_Month_Total"><Val xsi:type="xsd:float">0.00</Val></Column> 
<Column name="MAR_Month_Total_B"><Val xsi:type="xsd:float">5.00</Val></Column> 
</Row> 
<Row RowNum="5"> 
<Column name="Title 1"><Val xsi:type="xsd:string">Sample 5</Val></Column> 
<Column name="Title 2"><Val xsi:type="xsd:string">Sample 6</Val></Column> 
<Column name="Title 3"><Val xsi:type="xsd:string">Sample 7</Val></Column> 
<Column name="Title 4"><Val xsi:type="xsd:string">Sample 8</Val></Column> 
<Column name="Title 5"><Val xsi:type="xsd:string">250X600</Val></Column> 
<Column name="Title 6"><Val xsi:type="xsd:string" xsi:nil="true"></Val></Column> 
<Column name="Title 7"><Val xsi:type="xsd:integer">5600</Val></Column> 
<Column name="APR_Month_ID"><Val xsi:type="xsd:integer">4</Val></Column> 
<Column name="YEAR"><Val xsi:type="xsd:integer">2012</Val></Column> 
<Column name="APR_Month_Total"><Val xsi:type="xsd:float">18.00</Val></Column> 
<Column name="APR_Month_Total_B"><Val xsi:type="xsd:float">35.00</Val></Column> 
</Row> 
<Row rowNum"6"> 
<Column name="Title 1"><Val xsi:type="xsd:string">Sample 5</Val></Column> 
<Column name="Title 2"><Val xsi:type="xsd:string">Sample 6</Val></Column> 
<Column name="Title 3"><Val xsi:type="xsd:string">Sample 7</Val></Column> 
<Column name="Title 4"><Val xsi:type="xsd:string">Sample 8</Val></Column> 
<Column name="Title 5"><Val xsi:type="xsd:string">250X600</Val></Column> 
<Column name="Title 6"><Val xsi:type="xsd:string" xsi:nil="true"></Val></Column> 
<Column name="Title 7"><Val xsi:type="xsd:integer">5600</Val></Column> 
<Column name="MAY_Month_ID"><Val xsi:type="xsd:integer">5</Val></Column> 
<Column name="YEAR"><Val xsi:type="xsd:integer">2012</Val></Column> 
<Column name="MAY_Month_Total"><Val xsi:type="xsd:float">18.00</Val></Column> 
<Column name="MAY_Month_Total_B"><Val xsi:type="xsd:float">35.00</Val></Column> 
</ROW> 
</DataSet> 
</ReportData> 
</Report> 

<?xml version="1.0"?> 
<?xml-stylesheet type="txt/xsl" href="transform.xsl"?> 
<Report> 
<ReportData> 
<DataSet> 
<Row rowNum="1"> 
<Column name="Title 1"><Val xsi:type="xsd:string">Sample 1</Val></Column> 
<Column name="Title 2"><Val xsi:type="xsd:string">Sample 2</Val></Column> 
<Column name="Title 3"><Val xsi:type="xsd:string">Sample 3</Val></Column> 
<Column name="Title 4"><Val xsi:type="xsd:string">Sample 4</Val></Column> 
<Column name="Title 5"><Val xsi:type="xsd:string">160X600</Val></Column> 
<Column name="Title 6"><Val xsi:type="xsd:string" xsi:nil="true"></Val></Column> 
<Column name="Title 7"><Val xsi:type="xsd:integer">1325600</Val></Column> 
<Column name="MAR_Month_Total"><Val xsi:type="xsd:float">19.00</Val></Column> 
<Column name="MAR_Month_Total_B"><Val xsi:type="xsd:float">22.00</Val></Column> 
<Column name="APR_Month_Total"><Val xsi:type="xsd:float">18.00</Val></Column> 
<Column name="APR_Month_Total_B"><Val xsi:type="xsd:float">35.00</Val></Column> 
<Column name="MAY_Month_Total"><Val xsi:type="xsd:float">25.00</Val></Column> 
<Column name="MAY_Month_Total_B"><Val xsi:type="xsd:float">15.00</Val></Column> 
</Row> 
<RowNum="2"> 
<Column name="Title 1"><Val xsi:type="xsd:string">Sample 5</Val></Column> 
<Column name="Title 2"><Val xsi:type="xsd:string">Sample 6</Val></Column> 
<Column name="Title 3"><Val xsi:type="xsd:string">Sample 7</Val></Column> 
<Column name="Title 4"><Val xsi:type="xsd:string">Sample 8</Val></Column> 
<Column name="Title 5"><Val xsi:type="xsd:string">250X600</Val></Column> 
<Column name="Title 6"><Val xsi:type="xsd:string" xsi:nil="true"></Val></Column> 
<Column name="Title 7"><Val xsi:type="xsd:integer">5600</Val></Column> 
<Column name="MAR_Month_Total"><Val xsi:type="xsd:float">0.00</Val></Column> 
<Column name="MAR_Month_Total_B"><Val xsi:type="xsd:float">5.00</Val></Column> 
<Column name="APR_Month_Total"><Val xsi:type="xsd:float">24.00</Val></Column> 
<Column name="APR_Month_Total_B"><Val xsi:type="xsd:float">10.00</Val></Column> 
<Column name="MAY_Month_Total"><Val xsi:type="xsd:float">36.00</Val></Column> 
<Column name="MAY_Month_Total_B"><Val xsi:type="xsd:float">15.00</Val></Column></Row> 
</DataSet> 
</ReportData> 
</Report> 

例欣賞任何幫助。 感謝

+0

兩個問題:1。將始終一個月佔用連續兩列,或莫不是不同數量的連續列的一個月? 2.您是否從年度開始 - 所提供的XML文檔中沒有任何此類數據。 – 2012-02-29 22:05:10

+0

是的。月銷售額總是會有兩列。一個是Gross,另一個是網絡。加上MonthID的一列。年份總是會在正在運行的報告的當年。謝謝 – Icudycm 2012-03-02 03:01:31

回答

0

試試這個:

<!--- you need to complete this variable with all month keys: --> 
<xsl:variable name="monthCodes" select="('JAN','FEB','MAR','APR','MAY','...')"/> 
<xsl:template match="Row"> 
    <!-- saves the month-total columns in a variable--> 
    <xsl:variable name="months" select="Column[contains(@name,'Month_Total')]"/> 
    <!-- groups the $months: starts a new group, if the @name is matching on the regex 'Month_Total$' --> 
    <xsl:for-each-group select="$months" group-starting-with="*[matches(@name,'Month_Total$')]"> 
     <Row> 
      <xsl:variable name="rowNum" select="count(../preceding-sibling::Row/Column[matches(@name,'Month_Total$')]) + position()"/> 
      <xsl:attribute name="rowNum" select="$rowNum"/> 
      <!-- copies all Columns of the current <Row> witch are not in $months --> 
      <xsl:copy-of select="../Column[not(contains(@name,'Month_Total'))]"/> 
      <xsl:variable name="monthCode" select="substring(@name,1,3)"/> 
      <Column name="{$monthCode}_Month_ID"> 
       <Val xsi:type="xsd:integer"> 
        <xsl:value-of select="index-of($monthCodes,$monthCode)"/> 
       </Val> 
      </Column> 
      <Column name="YEAR"> 
       <Val xsi:type="xsd:integer"><xsl:value-of select="year-from-date(current-date())"/></Val> 
      </Column> 
      <!-- copies all nodes of the current Row (the mont h-total columns of the current month) --> 
      <xsl:copy-of select="current-group()"/> 
     </Row> 
    </xsl:for-each-group> 
</xsl:template> 
<xsl:template match="node() | @*"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*"/> 
     <xsl:apply-templates select="node()"/> 
    </xsl:copy> 
</xsl:template>