2011-03-25 42 views
1
<grid> 
<col>Links</col> 
<col>Rechts</col> 
<row> 
    <Links>l1</Links> 
    <Rechts>r1</Rechts> 
</row> 
<row> 
    <Links>l2</Links> 
    <Rechts>r2</Rechts> 
</row> 
</grid> 

嘿夥計,給出的XML數據上面我想創建一個表,如:在運行時評估XPath表達式還是使用其他方法?

Links|Rechts 
l1|r1 
l2|r2 

我的XSL模板是:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:dyn="http://exslt.org/dynamic" 
extension-element-prefixes="dyn"> 

    <xsl:template match="grid"> 

     <xsl:for-each select="//row"> 
      <xsl:variable name="currentrow" select="."/> 
      <xsl:for-each select="//col"> 
       <xsl:variable name="colname" select="text()"/> 
       <xsl:value-of select="dyn:evaluate('$currentrow/$colname/text()')"></xsl:value-of> 
      </xsl:for-each> 
     </xsl:for-each> 
    </xsl:template> 

</xsl:stylesheet> 

我得到的唯一的輸出是 「」。

我不知道如何解決我的問題。我不知道事件是否正確使用dyn:評估。

感謝您的幫助!

+0

好問題,+1。查看我的答案最短 - 作爲模板的數量或行數 - 完整的解決方案,可以適應缺少col元素或順序。 – 2011-03-26 16:51:45

回答

0

這個樣式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:variable name="vColNames" select="/grid/col"/> 
    <xsl:template match="grid"> 
     <table> 
      <xsl:apply-templates/> 
     </table> 
    </xsl:template> 
    <xsl:template match="col"/> 
    <xsl:template match="col[1]"> 
     <tr> 
      <xsl:apply-templates select="../col" mode="wrap"/> 
     </tr> 
    </xsl:template> 
    <xsl:template match="col" mode="wrap"> 
     <th> 
      <xsl:apply-templates/> 
     </th> 
    </xsl:template> 
    <xsl:template match="row"> 
     <xsl:variable name="vCurrent" select="."/> 
     <tr> 
      <xsl:for-each select="$vColNames"> 
       <xsl:apply-templates select="$vCurrent/*[name()=current()]"/> 
      </xsl:for-each> 
     </tr> 
    </xsl:template> 
    <xsl:template match="row/*"> 
     <td> 
      <xsl:apply-templates/> 
     </td> 
    </xsl:template> 
</xsl:stylesheet> 

輸出:

<table> 
    <tr> 
     <th>Links</th> 
     <th>Rechts</th> 
    </tr> 
    <tr> 
     <td>l1</td> 
     <td>r1</td> 
    </tr> 
    <tr> 
     <td>l2</td> 
     <td>r2</td> 
    </tr> 
</table> 

注意:遍歷列在row上下文名稱。

+0

感謝您的回覆。你能告訴我如何刪除$ vColNames中每個元素的所有空格嗎? – markusf 2011-03-29 18:29:54

+0

@markusf:不客氣。你是說你有一些像' Rechts'這樣的元素? – 2011-03-29 18:36:14

+0

亞歷杭德羅,有點兒。例如:「Col Name」 – markusf 2011-03-29 20:22:55

1

<xsl:template match="grid"> 
    <xsl:for-each select="row"> 
      <xsl:value-of select="Links"/>| 
      <xsl:value-of select="Rechts"/><br> 
    </xsl:for-each> 
</xsl:template> 

我已經使用<br>一個換行符替換您的XSLT grid部分,如果這不是HTML,使用相關的符號(S)。

+0

這不是動態的 – markusf 2011-03-25 22:15:09

+0

你沒有提到你的問題,這需要使用任何動態:東西。我的(我相信Tomalak的)代碼正常工作。這不是你想要達到的目標嗎? – mindas 2011-03-25 22:18:02

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

    <xsl:template match="grid"> 
    <xsl:apply-templates select="col" /> 
    <xsl:apply-templates select="row" /> 
    </xsl:template> 

    <xsl:template match="col|row/*"> 
    <xsl:value-of select="." /> 
    <xsl:choose> 
     <xsl:when test="position() = last()"><xsl:value-of select="'&#xA;'" /></xsl:when> 
     <xsl:otherwise>|</xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet> 

  • 的XPath沒有動態評估是必要的這一點。
  • <xsl:strip-space elements="*">刪除,否則將出現在輸出
  • 相同的模板可以(通過聯合運營|這裏)
  • 該解決方案可與任意數量的列應付搭配不同的節點只有空白文本節點
  • 沒關係的數據字段的命名方式,因爲我用row/*

編輯更詳細的版本,確實沒有假設每一列都在那裏。

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

    <xsl:template match="grid"> 
    <xsl:apply-templates select="col" /> 
    <xsl:apply-templates select="row" /> 
    </xsl:template> 

    <xsl:template match="col"> 
    <xsl:value-of select="." /> 
    <xsl:call-template name="separator" /> 
    </xsl:template> 

    <xsl:template match="row"> 
    <xsl:variable name="this" select="." /> 
    <xsl:for-each select="/grid/col"> 
     <xsl:value-of select="$this/*[name() = current()]" /> 
     <xsl:call-template name="separator" /> 
    </xsl:for-each> 
    </xsl:template> 

    <xsl:template name="separator"> 
    <xsl:choose> 
     <xsl:when test="position() = last()"><xsl:value-of select="'&#xA;'" /></xsl:when> 
     <xsl:otherwise>|</xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet> 
+0

哇,謝謝,它的作品,現在我試圖理解它。好吧,它很容易。但是,如果連線上缺少一些色譜柱,它就無法工作。我必須檢查我的數據模型,如果可能的話。 – markusf 2011-03-25 22:16:39

+0

@markusf:這是正確的,假設列的名稱匹配每個字段,並按照確切的順序執行。 – 2011-03-25 22:20:23

+0

@markusf如果是這樣,事情會變得更復雜一點。如果您需要將列名與列匹配的解決方案,那也是可能的。 – Tomalak 2011-03-25 22:21:48

0

該轉化(具有模板的最小的數 - 僅有3,和比其他所有當前解決方案更短的,和有彈性的,以元素順序或丟失col元素):

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

<xsl:template match="col[not(position()=last())]"> 
    <xsl:value-of select="concat(.,'|')"/> 
</xsl:template> 

<xsl:template match="row"> 
    <xsl:text>&#xA;</xsl:text> 
    <xsl:apply-templates select="/*/col" 
     mode="buildCell"> 
    <xsl:with-param name="pRow" select="."/> 
    </xsl:apply-templates> 
</xsl:template> 

<xsl:template match="col" mode="buildCell"> 
    <xsl:param name="pRow"/> 

    <xsl:value-of select= 
    "concat($pRow/*[name()=current()], 
      substring('|', (position()=last())+1) 
      ) 
    "/> 
</xsl:template> 
</xsl:stylesheet> 

當施加上所提供的XML文檔:

<grid> 
    <col>Links</col> 
    <col>Rechts</col> 
    <row> 
     <Links>l1</Links> 
     <Rechts>r1</Rechts> 
    </row> 
    <row> 
     <Links>l2</Links> 
     <Rechts>r2</Rechts> 
    </row> 
</grid> 

產生想要的,正確的結果:

Links|Rechts 
l1|r1 
l2|r2