2010-08-05 65 views
4

我想創建一個網站,其中(除其他事項外),將顯示其包含在XML文件中的數據。我使用xsl樣式表來格式化一切,但有些頁面有類似的內容。有沒有辦法讓xsl顯示數據的顯示位置,並確定要使用哪種佈局。動態決定使用哪個XSL樣式表

例子:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:template match="/"> 

<xsl:choose> 
    <xsl:if test="something"> 
    <!-- Format data one way --> 
    </xsl:if> 
    <xsl:otherwise> 
    <!-- Format data another way --> 
    </xsl:otherwise> 
</xsl:choose> 

</xsl:template> 
</xsl:stylesheet> 

該網站正在以更大的網站不允許其微型網站使用任何服務器端腳本,所以我選擇在這裏嚴重限制託管。

+0

好問題(+1)。請參閱我的回答,解釋「填充空白」XSLT設計模式。 – 2010-08-05 19:56:07

回答

0

你可以使用客戶端XSLT。在你的XML文檔中提供一個PI,在特定的樣式表中包含主佈局樣式表。

可自由查詢和使用http://www.aranedabienesraices.com.ar爲例。

編輯3:遞歸幾乎完整的例子。

XML文檔 「layoutA.xml」:

<html xmlns:inc="include"> 
    <body> 
     <h1>Birthday</h1> 
     <dl inc:in-iter="person"> 
      <dt inc:path="name"></dt> 
      <dd inc:path="date"></dd> 
     </dl> 
    </body> 
</html> 

輸入XML文檔:

<data> 
    <person> 
     <name>Bob</name> 
     <date>2010-02-23</date> 
     <link>http://example.org/bob</link> 
    </person> 
    <person> 
     <name>Alex</name> 
     <date>2010-02-23</date> 
     <link>http://example.org/alex</link> 
    </person> 
</data> 

樣式表:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:inc="include"> 
    <xsl:param name="pLayout" select="'layoutA.xml'"/> 
    <xsl:template match="/"> 
     <xsl:apply-templates select="document($pLayout)/*"> 
      <xsl:with-param name="context" select="*"/> 
     </xsl:apply-templates> 
    </xsl:template> 
    <xsl:template match="@*|node()"> 
     <xsl:param name="context"/> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"> 
       <xsl:with-param name="context" select="$context"/> 
      </xsl:apply-templates> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="*[@inc:path]"> 
     <xsl:param name="context"/> 
     <xsl:copy> 
      <xsl:apply-templates select="@*"> 
       <xsl:with-param name="context" select="$context"/> 
      </xsl:apply-templates> 
      <xsl:value-of select="$context/*[name()=current()/@inc:path]"/> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="*[@inc:in-iter]" priority="1"> 
     <xsl:param name="context"/> 
     <xsl:variable name="me" select="."/> 
     <xsl:copy> 
      <xsl:apply-templates select="@*"> 
       <xsl:with-param name="context" select="$context"/> 
      </xsl:apply-templates> 
      <xsl:for-each select="$context/*[name()=current()/@inc:in-iter]"> 
       <xsl:apply-templates select="$me/node()"> 
        <xsl:with-param name="context" select="."/> 
       </xsl:apply-templates> 
      </xsl:for-each> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="*[@inc:out-iter]" priority="1"> 
     <xsl:param name="context"/> 
     <xsl:variable name="me" select="."/> 
     <xsl:for-each select="$context/*[name()=current()/@inc:out-iter]"> 
      <xsl:element name="{name($me)}" namespace="{namespace-uri($me)}"> 
       <xsl:apply-templates select="$me/@*|$me/node()"> 
        <xsl:with-param name="context" select="."/> 
       </xsl:apply-templates> 
      </xsl:element> 
     </xsl:for-each> 
    </xsl:template> 
    <xsl:template match="@inc:path|@inc:in-iter|@inc:out-iter" priority="1"/> 
    <xsl:template match="@inc:*"> 
     <xsl:param name="context"/> 
     <xsl:attribute name="{local-name()}"> 
      <xsl:value-of select="$context/*[name()=current()]"/> 
     </xsl:attribute> 
    </xsl:template> 
</xsl:stylesheet> 

輸出:

<html xmlns:inc="include"> 
    <body> 
     <h1>Birthday</h1> 
     <dl> 
      <dt>Bob</dt> 
      <dd>2010-02-23</dd> 
      <dt>Alex</dt> 
      <dd>2010-02-23</dd> 
     </dl> 
    </body> 
</html> 

傳遞PARAM pLayout'layoutB.xml',而這個 「layoutB.xml」:

<html xmlns:inc="include"> 
    <body> 
     <h1>Friends</h1> 
     <ul> 
      <li inc:out-iter="person"> 
       <a inc:href="link" inc:path="name"></a> 
      </li> 
     </ul> 
    </body> 
</html> 

輸出:

<html xmlns:inc="include"> 
    <body> 
     <h1>Friends</h1> 
     <ul> 
      <li> 
       <a href="http://example.org/bob">Bob</a> 
      </li> 
      <li> 
       <a href="http://example.org/alex">Alex</a> 
      </li> 
     </ul> 
    </body> 
</html> 

注意:你requeriment的主要問題是相同的文件限制(因此,相同的文檔URI,沒有不同的PI,沒有不同的佈局URI元數據),只讓你傳遞給佈局URI參數。直到瀏覽器支持XPath 2.0 fn:document-uri(),以便您可以解析URL查詢。當然,你可以使用一些擴展(例如MSXSL script),但使它跨瀏覽器工作會很困難。

+0

這裏的問題是每個xml文檔仍然只能以一種方式進行樣式化。我想不要有一個主佈局樣式表。 – Skunkwaffle 2010-08-05 18:49:49

+0

@Skunkwaffle:每個XML輸入文檔都可以有自己的樣式表,也可以保留一個主文檔(或者對於相同文檔相同)的樣式表。檢查我的編輯和我的**鏈接** – 2010-08-05 19:30:55

+0

這仍然需要兩個不同的XML文件。我想要的是A.xml,使用master.xsl或b.xsl,取決於它顯示的位置。 – Skunkwaffle 2010-08-05 19:38:58

1

在這種情況下,我使用的佈局中,每個包含在單獨的XML文檔英寸

佈局使用(的文件名)可以作爲一個參數到變換來傳遞,或者它可以改造內被動態地確定。

從這一刻起,佈局XML文檔可以使用XSLT文檔進行訪問()函數:

<xsl:variable name="vDocLayout" select="document($pLayout)"/> 

然後你就可以發出:

<xsl:apply-templates select="$vDocLayout"/> 

這是「fill in the blanks」XSLT設計模式

+0

@Dimitre:是的。我使用這種模式,這就是爲什麼我已經發布鏈接到我的商業網站作爲生動的例子。但是,因爲瀏覽器上沒有XPath 2.0支持,所以不能使用'fn:document-uri()'作爲傳遞參數的方式。所以,你必須不斷髮送PI到不同的樣式表,至少只是聲明你的'pLayout'參數,或者把它的uri與元數據一起添加到你的XML文檔中(大部分是添加PI的相同任務)。在數據和佈局URI之間進行某種內聯映射是可行的,但是使得該站點不那麼動態...... – 2010-08-05 20:34:34

+0

@Dimitre:另外,我稱這種轉換(單獨的佈局文檔和數據文檔)爲「人口」,因爲它更像是使用.Net – 2010-08-05 20:42:04

+0

@Ajjandro的良好代碼實踐:只有在客戶端處理中使用此設計模式沒有限制。在服務器端,所有可能的平臺都支持將參數傳遞給轉換。 – 2010-08-05 20:56:20