2012-05-14 36 views
1

尋求一個完美的解決方案,以XML轉換成HTML樹視圖(我已經廣泛使用,但沒有研究這個問題找到一個適當的解決辦法呢。)使用XSLT

我使用XSLT轉換了一系列的XML文件到一個「樹狀」HTML文檔,其中元素之間的父子關係通過縮進來反映。

下面的解決方案工作正常,但它太冗長了,我們還需要適應將來添加一些新的 元素到模式。

什麼是一種很好的通用解決方案,能夠滿足我們的需求?我在網上看到了使用「深度」變量的遞歸解決方案,並遞增並作爲參數傳入,並用於驅動縮進級別;這似乎是一種常見的模式,但我無法讓它爲我工作。

謝謝。

所以我的數據文件看起來像這樣:

<document> 
    <metadata> 
    <version>1.0</version> 
    <date>1/1/12</date> 
    etc... 
    </metadata> 
    <trackdata> 
    <tracks> 
     <track>123</track> 
     <track>456</track> 
     etc... 
    </trackdata> 
</document> 

而XSLT(注意文本縮進不同的值,在不同層次):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="html" indent="no"/> 
    <xsl:template match="@*|node()"> 
     <xsl:apply-templates select="@*|node()" /> 
    </xsl:template> 

     <xsl:template match="metadata"> 
      Metadata: <xsl:apply-templates/> 
     </xsl:template> 

     <xsl:template match="version"> 
      <div style="text-indent:3em">Version: <xsl:value-of select="text()"/></div> 
     </xsl:template> 

     <xsl:template match="date"> 
      <div style="text-indent:3em">Date: <xsl:value-of select="text()"/></div> 
     </xsl:template> 

     <xsl:template match="trackdata"> 
      Track Data: <xsl:value-of select="text()"/></div> 
     </xsl:template> 

     <xsl:template match="tracks"> 
      <div style="text-indent:3em">Tracks: <xsl:apply-templates/> 
     </xsl:template> 

     <xsl:template match="track"> 
      <div style="text-indent:6em">Track: <xsl:value-of select="text()"/></div> 
     </xsl:template> 

等等

回答

2

嘗試創建一個變量來保存text-indent值。事情是這樣的:

<xsl:template match="version"> 
    <xsl:variable name="vIndent" select="count(ancestor::*) * 3"/>  
    <div style="text-indent:{$vIndent}em">Version: <xsl:value-of select="text()"/></div> 
    </xsl:template> 

這裏使用的另一個完整的例子...

XML輸入(良構)

<document> 
    <metadata> 
    <version>1.0</version> 
    <date>1/1/12</date> 
    </metadata> 
    <trackdata> 
    <tracks> 
     <track>123</track> 
     <track>456</track> 
    </tracks> 
    </trackdata> 
</document> 

XSLT 1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="html" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="text()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
    </xsl:template> 

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

    <xsl:template match="*"> 
    <xsl:variable name="vIndent" select="count(ancestor::*) * 3"/> 
    <div style="text-indent:{$vIndent}em"><xsl:value-of select="name()"/>: <xsl:apply-templates/></div> 
    </xsl:template> 

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

</xsl:stylesheet> 

原始HTML輸出

<html> 
    <div style="text-indent:3em">metadata: 
     <div style="text-indent:6em">version: 1.0</div> 
     <div style="text-indent:6em">date: 1/1/12</div> 
    </div> 
    <div style="text-indent:3em">trackdata: 
     <div style="text-indent:6em">tracks: 
     <div style="text-indent:9em">track: 123</div> 
     <div style="text-indent:9em">track: 456</div> 
     </div> 
    </div> 
</html> 

如果你想第一個div到沒有縮進,你可以在變量改成這樣:

<xsl:variable name="vIndent" select="(count(ancestor::*) * 3) - 3"/> 
+0

感謝DevNull!今天會嘗試! – bethesdaboys

+0

非常歡迎你@bethesdaboys –