2010-08-20 115 views
1

我最近問了一個關於使用XSL/t創建網站佈局和子頁面Here的問題。佈局會修飾子頁面。我想擴展這個想法,並提出像SiteMesh功能。請注意,我將只有很少的xsl佈局文件,我的xsl文件大部分都應該用於子頁面。佈局相當基本,它包含一個標題,一個主菜單,一個頁腳,一個主體有一個內容div在它下面。 SiteMesh允許您將模板文件定義爲一個相當標準的html文件,然後將子頁面覆蓋父項的各個部分。 舉例來說,這裏是SiteMesh的一個基本的模板(裝飾):Sitemesh類似於XSLT的功能嗎?

<%@ taglib prefix="decorator" uri="http://www.opensymphony.com/sitemesh/decorator" %> 

<head> 
    <title> 
    <decorator:title default="SiteMesh Tutorial Example" /> - Site Title 
    </title> 
    <style type="text/css">@import "css/global.css";</style> 
    <decorator:head /> 
    <body> 
    <div id="header"> 
     <h2><a href="http://www.my-site.com/">Mysite.com</a> goes here</h2> 
    </div> 
    <div id="content"> 
     <decorator:body /> 
    </div> 
    </body> 
</html> 

然後在這裏將是一個子頁面的例子:一旦裝飾被應用到子頁面

<html> 
    <head> 
    <title>Child Page</title> 
    <style type='text/css'> 
    p { margin: 10 }  
    </style> 
    </head> 
    <body> 
    Content Goes here 
    </body> 
</html> 

,其結果 包含兒童頁的主體,其中裝飾者:身體在和裝飾者:頭被取代,等等。 很簡單,它如何工作和相當有效的方式orga確定一個網站。

因此,現在讓我們說我們使用XSL/T,而我們希望使用類似的結構,我們不會重新定義佈局的樣子,而是希望只定義一次(或者幾次不是很相似的頁面),如果子模板具有它們,我們會替換掉部分。 聽起來這將是非常簡單的,但問題是,支持本網站的數據看起來就像是(不是一個真正的博客網站,但就像我正在處理的一個例子)

<xml> 
<section>Blogs</section> 
<page>UserBlogs</page> 
<data> 
<blogs> 
    <blog> 
    <title>First Blog</title> 
    <author>John Doe</author> 
    <description>...</description> 
    </blog> 
</blogs> 
</data> 
</xml> 

所以現在比方說,我有一個主模板是這樣的:

<html> 
<head> 
    <title><!-- replace this with child title --> - Site Title</title> 
    <script src="common-scripts.js"></script> 
    <style type="text/css">@import "common.css" </style> 
    <!-- insert everything in the child <head> here except the title --> 

</head> 
<body> 
    <div id="header">Header/log that stuff here</div> 
    <div id="menu"> 
    <ul><li><a href="#">Cat 1</a></li><li><a href="#">Cat 2</a></li></ul> 
    </div> 
    <div id="content"> 
    <!-- replace this with everything between <body>...</body> in the child --> 
    </div> 
    <div id="footer">My Site, copyright, bla bla</div> 
</body> 
</html> 

,那麼什麼我想要做的就是採取從上面的XML(一種對博客),並應用到我的子頁面,並利用該結果轉換並將其應用到我的主模板(將根據需要複製/應用元素)。 我不確定是否有辦法在單個轉換中執行此操作。 目前的架構是這樣的,我所提供的XML如圖所示,我必須構建成一個頁面..我想也許我可以讓主模板包含子模板,然後使用xsl:call-template包裝在xsl:variable聲明中捕獲當前xml上的子模板的結果。我需要以某種方式將該轉換的結果替換爲主模板title/header/content部分。

任何想法如何做到這一點?

我看到這個網站:http://www.devguru.com/technologies/xslt/quickref/xslt_element_calltemplate.html ,你可以捕捉XSL的結果:調用模板在xsl:變量聲明我只是困惑你怎麼可以再使用這些數據除了ouputing吧..

任何幫助,將不勝感激

+0

@Matt Wolfe:這是微不足道的完成。唯一的問題是你還沒有定義如何一起處理「子模板」和你的XML文件,以產生「最終階段子模板」。定義這一點,我將提供一個完整和詳細的解決方案。 – 2010-08-20 16:10:47

+0

@Ajjandro - 您的網站不是我的語言,谷歌翻譯不能使用它。我沒有看到任何教程或示例。我第一次檢查它,我再次檢查它,它看起來像是房地產或其他東西。 – 2010-08-20 19:18:53

+0

@Dimitre, 我的網站的後端生成一些XML,如我所示。該框架允許您指定一個xsl文檔,您將使用它來處理xml。現在我正在使用一個全面的樣式表,無論用戶轉到哪個頁面,都使用Main.xsl這是佈局。然後,該佈局查看/ xml/section和/ xml /頁面以確定要使用哪個子模板。我正在考慮通過修改後端代碼首先應用子樣式表來完成2部分轉換,然後將佈局樣式表應用於該..我寧願不這樣做,儘管如果可能的話。 – 2010-08-20 19:22:47

回答

2

有了這個輸入:

<xml> 
    <section>Blogs</section> 
    <page>UserBlogs</page> 
    <data> 
     <blogs> 
      <blog> 
       <title>First Blog</title> 
       <author>John Doe</author> 
       <description>...</description> 
      </blog> 
     </blogs> 
    </data> 
</xml> 

這種 「master.xml」 文件:

<html> 
    <head> 
     <title><!-- replace this with child title --> - My Site</title> 
     <script src="common-scripts.js"></script> 
     <style type="text/css">@import "common.css" </style> 
     <!-- insert everything in the child <head> here except the title --> 
    </head> 
    <body> 
     <div id="header">Header/log that stuff here</div> 
     <div id="menu"> 
      <ul> 
       <li> 
        <a href="#">Cat 1</a> 
       </li> 
       <li> 
        <a href="#">Cat 2</a> 
       </li> 
      </ul> 
     </div> 
     <div id="content"> 
      <!-- replace this with everything between 
            <body>...</body> in the child --> 
     </div> 
     <div id="footer">My Site, copyright, bla bla</div> 
    </body> 
</html> 

這個「小孩。XML」的文件:

<html> 
    <head> 
     <title>Child Page</title> 
     <style type='text/css'>p { margin: 10 }</style> 
    </head> 
    <body> 
     <h3 id="title">#</h3> 
     <dl> 
      <dt id="author">#</dt> 
      <dd id="description">#</dd> 
     </dl> 
    </body> 
</html> 

這個樣式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml"/> 
    <xsl:variable name="child" select="document('child.xml')"/> 

    <!-- From here to next comment could be in other stylesheet 
     like "master.xsl" and included with "xsl:include"  --> 

    <xsl:variable name="master" select="document('master.xml')"/> 
    <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="/"> 
     <xsl:apply-templates select="$master/*"> 
      <xsl:with-param name="context" select="/"/> 
     </xsl:apply-templates> 
    </xsl:template> 
    <xsl:template match="div[@id='content']"> 
     <xsl:param name="context"/> 
     <xsl:copy> 
      <xsl:apply-templates select="@*"/> 
      <xsl:for-each select="$context/xml/data/blogs/blog"> 
       <xsl:apply-templates select="$child/html/body/node()"> 
        <xsl:with-param name="context" select="."/> 
       </xsl:apply-templates> 
      </xsl:for-each> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="title/comment()"> 
     <xsl:param name="context"/> 
     <xsl:value-of select="$context/xml/page"/> 
    </xsl:template> 
    <xsl:template match="head/comment()"> 
     <xsl:param name="context"/> 
      <xsl:apply-templates 
          select="$child/html/head/node()[not(self::title)]"> 
       <xsl:with-param name="context" select="$context"/> 
      </xsl:apply-templates> 
    </xsl:template> 

    <!-- Here ends the posible "master.xsl" to be included --> 

    <xsl:template match="@id[.='title']|@id[.='author']|@id[.='description']"/> 
    <xsl:template match="*[@id='title']/text()"> 
     <xsl:param name="context"/> 
     <xsl:value-of select="$context/title"/> 
    </xsl:template> 
    <xsl:template match="*[@id='author']/text()"> 
     <xsl:param name="context"/> 
     <xsl:value-of select="$context/author"/> 
    </xsl:template> 
    <xsl:template match="*[@id='description']/text()"> 
     <xsl:param name="context"/> 
     <xsl:value-of select="$context/description"/> 
    </xsl:template> 
</xsl:stylesheet> 

輸出:

<html> 
    <head> 
     <title>UserBlogs - My Site</title> 
     <script src="common-scripts.js"></script> 
     <style type="text/css">@import "common.css" </style> 
     <style type="text/css">p { margin: 10 }</style> 
    </head> 
    <body> 
     <div id="header">Header/log that stuff here</div> 
     <div id="menu"> 
      <ul> 
       <li> 
        <a href="#">Cat 1</a> 
       </li> 
       <li> 
        <a href="#">Cat 2</a> 
       </li> 
      </ul> 
     </div> 
     <div id="content"> 
      <h3 id="title">First Blog</h3> 
      <dl> 
       <dt id="author">John Doe</dt> 
       <dd id="description">...</dd> 
      </dl> 
     </div> 
     <div id="footer">My Site, copyright, bla bla</div> 
    </body> 
</html> 

注意:這只是一個例子可以更好地對人口格局了校長的問題:邏輯是遍歷佈局,而不是數據,主要是身份變換;您需要在佈局中引入一些錨以引用數據(this例如,通過自己的命名空間,通過像id="include:some-data"等特定模式)是開放的。你需要刪除那些錨點,如果他們是@id;對於文本替換,在佈局中使用虛擬文本節點,這簡化了內容模板,僅爲xsl:value-of; 「窮人的隧道模式」(迪米特呼籲)通過數據背景,主要是因爲迭代人口。其他問題:當處理XHTML(比HTML更好)時,注意:DOCTYPE主要用於IE7(否則改進的CSS處理鬆散),DTD中聲明的空元素(否則爲<br />的錯誤行爲)。請隨時查看我之前發佈的網站,看看我是如何處理這些網站的。