2011-02-05 30 views
1

我想根據XML值(1,2,3,4)的返回值來顯示頁面A,B,C,D。我的方法是通過JavaScript或XSLT:選擇。我想知道哪種方式更好,爲什麼?我可以做這種情況 - 選擇.cs代碼(好還是壞)?我應該在XSLT的JavaScript代碼?社區可以提供建議嗎?謝謝。良好的編碼風格在XSLT中進行大小寫選擇

下面是代碼。

的Javascript的方式(這一個工程):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:js="urn:custom-javascript"> 
    <xsl:template match="page"> 

    <msxsl:script language="JavaScript" implements-prefix="js"> 
     <![CDATA[ 
     function translateSkillLevel(level) 
     { 
      switch (level) 
      { 
      case 0: return "Level 1"; 
      case 1: return "Level 2"; 
      case 2: return "Level 3"; 
      } 
     return "unknown"; 
     } 
     ]]> 
    </msxsl:script> 

    <div id="skill"> 
     <table border="0" cellpadding="1" cellspacing="1"> 
     <tr> 
      <th>Level</th> 
     </tr> 
     <xsl:for-each select="/page/Skill"> 
      <tr> 
      <td> 
       <!-- difference here --> 
       <script type="text/javascript"> 
       document.write(translateSkillLevel(<xsl:value-of select="@level"/>)); 
       </script> 
      </td> 
      </tr> 

     </xsl:for-each> 
     </table> 
    </div> 
    </xsl:template> 
</xsl:stylesheet> 


的Javascript方式(這個是不行的,越來越不確定的JS代碼):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:js="urn:custom-javascript"> 
    <xsl:template match="page"> 

    <msxsl:script language="JavaScript" implements-prefix="js"> 
     <![CDATA[ 
     function translateSkillLevel(level) 
     { 
      switch (level) 
      { 
      case 0: return "Level 1"; 
      case 1: return "Level 2"; 
      case 2: return "Level 3"; 
      } 
     return "unknown"; 
     } 
     ]]> 
    </msxsl:script> 

    <div id="skill"> 
     <table border="0" cellpadding="1" cellspacing="1"> 
     <tr> 
      <th>Level</th> 
     </tr> 
     <xsl:for-each select="/page/Skill"> 
      <tr> 
      <td> 
       <!-- difference here --> 
       <xsl:value-of select="js:translateSkillLevel(string(@level))"/> 
      </td> 
      </tr> 

     </xsl:for-each> 
     </table> 
    </div> 
    </xsl:template> 
</xsl:stylesheet> 


XSLT方式:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="page"> 
    <div id="skill"> 
     <table border="0" cellpadding="1" cellspacing="1"> 
     <tr> 
      <th>Level</th> 
     </tr> 
     <xsl:for-each select="/page/Skill"> 
      <tr> 
      <td> 
       <xsl:choose> 
       <xsl:when test="@level = 0"> 
        Level 1 
       </xsl:when> 
       <xsl:when test="@level = 1"> 
        Level 2 
       </xsl:when> 
       <xsl:when test="@level = 2"> 
        Level 3 
       </xsl:when> 
       <xsl:otherwise> 
        unknown 
       </xsl:otherwisexsl:otherwise> 
       </xsl:choose> 
      </td> 
      </tr> 

     </xsl:for-each> 
     </table> 
    </div> 
    </xsl:template> 
</xsl:stylesheet> 



編輯: 另外,我有一些內嵌的JavaScript表單功能提交。

<input type="submit" onclick="javascript:document.forms[0].submit();return false;"/> 
+0

好問題,+1。查看我的答案,瞭解最可定製,靈活和可擴展的XSLT解決方案。同時它非常簡單,它甚至不包含單個選擇邏輯指令。 :) – 2011-02-05 18:32:29

回答

2

首先,XSLT的方法是這樣的:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="page"> 
     <div id="skill"> 
      <table border="0" cellpadding="1" cellspacing="1"> 
       <tr> 
        <th>Level</th> 
       </tr> 
       <xsl:apply-templates/> 
      </table> 
     </div> 
    </xsl:template> 
    <xsl:template match="Skill"> 
     <tr> 
      <td> 
       <xsl:apply-templates select="@level"/> 
      </td> 
     </tr> 
    </xsl:template> 
    <xsl:template match="@level">Unknown</xsl:template> 
    <xsl:template match="@level[3>.]"> 
     <xsl:value-of select="concat('Level ',.+1)"/> 
    </xsl:template> 
</xsl:stylesheet> 

輸入:

<page> 
    <Skill level="1"/> 
    <Skill level="4"/> 
</page> 

輸出:

<div id="skill"> 
    <table border="0" cellpadding="1" cellspacing="1"> 
     <tr> 
      <th>Level</th> 
     </tr> 
     <tr> 
      <td>Level 2</td> 
     </tr> 
     <tr> 
      <td>Unknown</td> 
     </tr> 
    </table> 
</div> 

二:您第一個樣式表不「工作「實際上,除非你定義了一些HTML SCRIPT元素,translateSkillLevel javascript功能(或更好,外部LINK)。

第三:您的第二個樣式表可以「工作」,但內聯擴展功能實現不是標準的XSLT擴展機制。這就是爲什麼你使用非標準擴展元素使你的樣式表在XSLT處理器之間不可移植。

3

在這兩個中,我絕對會選擇XSLT方式。沒有必要爲此調用整個腳本引擎。

+0

如果我的代碼有按鈕onclick =「javascript:document.forms [0] .submit();」會怎麼樣?也許腳本引擎只有在單擊按鈕時纔會被調用。不過,我的觀點是我在我的代碼中的其他地方使用JavaScript。 – Stan 2011-02-05 04:44:56

+2

@Stan:在你的輸出中有JavaScript是完全不相關的。 (順便說一句,從來沒有在任何地方使用「`javascript:`」 - 這是你做錯事的跡象) – 2011-02-05 04:54:47

1

沒有擴展功能是必要的,XSLT功能強大且足夠靈活。

的XSLT實現我建議是這樣的(主要是定製的,靈活和可擴展):

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:my="my:my" exclude-result-prefixes="my"> 

<my:skills> 
    <s v="0" d="1"/> 
    <s v="1" d="2"/> 
    <s v="2" d="3"/> 
    <other>unknown</other> 
</my:skills> 

<xsl:variable name="vSkills" select= 
    "document('')/*/my:skills/*"/> 

<xsl:variable name="vUnknown" select= 
    "document('')/*/my:skills/other"/> 

<xsl:template match="page"> 
    <div id="skill"> 
     <table border="0" cellpadding="1" cellspacing="1"> 
      <tr> 
       <th>Level</th> 
      </tr> 
      <xsl:apply-templates select="Skill/@level"/> 
     </table> 
    </div> 
</xsl:template> 

<xsl:template match="@level"> 
    <tr> 
    <td> 
     <xsl:variable name="vSkill" select= 
     "$vSkills[@v=current()]/@d"/> 
     <xsl:value-of select="$vSkill|$vUnknown[not($vSkill)]"/> 
    </td> 
    </tr> 
</xsl:template> 
</xsl:stylesheet> 

當上述轉換應用於以下XML文檔

<page> 
    <Skill level="1"/> 
    <Skill level="4"/> 
</page> 

想要的,正確的結果產生

<div id="skill"> 
    <table border="0" cellpadding="1" cellspacing="1"> 
     <tr> 
      <th>Level</th> 
     </tr> 
     <tr> 
      <td>2</td> 
     </tr> 
     <tr> 
      <td>unknown</td> 
     </tr> 
    </table> 
</div> 

請注意

  1. 所有用於轉換目前的技能值,顯示值的規則被指定爲數據

  2. 決策數據可以在一個單獨的文檔中,以便完成參數化。

  3. 我們不依賴意外依賴(如dispValue =值+1) - 可以表示當前值和顯示值之間的任何關係b/n。

  4. XSLT代碼中絕對沒有條件邏輯