2012-11-02 59 views
0

將動態xml數據解析爲html表時遇到問題。 XML如下。將動態XML解析爲html表

<results> 
    <result id="1" desc="Voltage and current"> 
    <measure desc="VOLT" value="1.0" /> 
    <measure desc="AMPERE" value="2.0" /> 
    </result> 
    <result id="2" desc="Current-1"> 
    <measure desc="AMPERE" value="5.0" /> 
    </result> 
</results> 

從中我想像一個HTML表:

ID DESC    VOLT AMPERE 
1 Voltage and current 1.0 2.0 
2 Current-1     5.0 

通知在第二電壓列中的空單元。 ID和DESC取自result/@ id和result/@ desc,其餘列名應來自measure/@ desc

沒有列名稱應該重複,我設法編碼那麼遠,但是當我開始添加我的措施,我需要將每個度量/ @ desc與表中正確的列匹配。我嘗試使用雙重嵌套循環來首先匹配所有唯一的列名稱,然後再次循環所有度量以匹配列標題。但是xslt解析器向我扔了一個NPE! 對不起,我無法顯示任何代碼,因爲它是在未連接的計算機上。

我瀏覽過這麼多的Q/A,但對我的具體問題沒有任何幫助。

在此先感謝

注:我能夠以任何方式更改的XML格式,使之更容易分析,如果有人想出了一個更簡潔的格式。

+0

是否使用XSLT1.0或者XSLT2.0? –

+0

我使用的是xslt 1.0 – styken

回答

1

如果您使用的是XSLT1.0,則可以使用名爲「Muenchian」分組的技術來獲取不同的度量說明,這將形成首行的基礎,並且還可用於輸出每行的值。

首先,您需要定義一個關鍵通過@desc查找措施元素屬性

<xsl:key name="measures" match="measure" use="@desc" /> 

然後,以獲得不同的措施描述,你可以在措施重複出現元素首先在給定的組中@desc屬性

<xsl:apply-templates 
    select="result/measure[generate-id() = generate-id(key('measures', @desc)[1])]" 
    mode="header" /> 

然後,對於您的標題,您只需要一個模板來輸出描述。

<xsl:template match="measure" mode="header"> 
    <th> 
     <xsl:value-of select="@desc" /> 
    </th> 
</xsl:template> 

對於每個結果行,會做類似的事情,並遍歷所有不同測量值,但唯一的區別是,你將不得不在當前結果元素作爲參數傳遞,用於以後使用。

<xsl:apply-templates 
    select="/results/result/measure[generate-id() = generate-id(key('measures', @desc)[1])]" 
    mode="data"> 
    <xsl:with-param name="result" select="." /> 
</xsl:apply-templates> 

然後,在相匹配的措施此時模板,你可以在結果元素內訪問措施具有匹配@desc屬性(和ID沒有這樣的屬性,沒什麼爲單元輸出)

<xsl:template match="measure" mode="data"> 
    <xsl:param name="result" /> 
    <td> 
     <xsl:value-of select="$result/measure[@desc = current()/@desc]/@value" /> 
    </td> 
</xsl:template> 

這裏是充分XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:key name="measures" match="measure" use="@desc" /> 

    <xsl:template match="/results"> 
     <table> 
     <tr> 
      <th>ID</th> 
      <th>DESC</th> 
      <xsl:apply-templates select="result/measure[generate-id() = generate-id(key('measures', @desc)[1])]" mode="header" /> 
     </tr> 
     <xsl:apply-templates select="result" /> 
     </table> 
    </xsl:template> 

    <xsl:template match="result"> 
     <tr> 
     <td><xsl:value-of select="@id" /></td> 
     <td><xsl:value-of select="@desc" /></td> 
     <xsl:apply-templates select="/results/result/measure[generate-id() = generate-id(key('measures', @desc)[1])]" mode="data"> 
      <xsl:with-param name="result" select="." /> 
     </xsl:apply-templates> 
     </tr> 
    </xsl:template> 

    <xsl:template match="measure" mode="header"> 
     <th> 
     <xsl:value-of select="@desc" /> 
     </th> 
    </xsl:template> 

    <xsl:template match="measure" mode="data"> 
     <xsl:param name="result" /> 
     <td> 
     <xsl:value-of select="$result/measure[@desc = current()/@desc]/@value" /> 
     </td> 
    </xsl:template> 
</xsl:stylesheet> 

注意使用模式屬性,因爲您有兩個模板匹配度量值元素,其功能方式不同。

當適用於您的XML輸入,輸出以下

<table> 
    <tr> 
     <th>ID</th> 
     <th>DESC</th> 
     <th>VOLT</th> 
     <th>AMPERE</th> 
    </tr> 
    <tr> 
     <td>1</td> 
     <td>Voltage and current</td> 
     <td>1.0</td> 
     <td>2.0</td> 
    </tr> 
    <tr> 
     <td>2</td> 
     <td>Current-1</td> 
     <td/> 
     <td>5.0</td> 
    </tr> 
</table> 
+0

謝謝!優秀的答案! – styken