XSLT布局动态内容区布局、内容、动态、XSLT

2023-09-03 04:20:24 作者:少年玩命不玩心,

我正在重建我们网站的UI部分,它是所有严重的JavaScript / AJAX基础(在没有更好的理由,并在一个相当低效的方式),使得后端现在做的大部分内容生成。这是一个C#.net应用程序。

I'm working on rebuilding the UI portion of our website which is all heavily javascript/ajax based (for no good reason and in a fairly inefficient way) such that the backend will now do most of the content generation. It is a C# .net application.

我们几乎所有的页(这有可能是40-50页)中有相同的基本布局。我是全新的,以XSLT,但我已经做了很多与MVC框架的工作,如春天(Java中,使用SiteMesh的布局),Symfony的(PHP),有点轨,以及其他几个。我喜欢有有一个或几个常见的模板,然后有一个特定的内容部分,在那里的页面具体的东西变的能力。我想不通这是怎么用XSLT完成。在这个应用程序我提供给我的值在XML支持XSLT页面的情况下,让我们把它叫做ContentXSL,谁的价值是XSL文件的名称 欲使用的页面的内容部分。我知道这是不可能的,但它会是不错的使用:

Almost all of our pages (which there are probably 40-50 pages) have the same basic layout. I am brand new to XSLT but I've done a lot of work with MVC frameworks such as Spring (java, using Sitemesh for layout), Symfony (PHP), a bit of rails as well as a few others. I love having the ability to have one or several common templates and then have a specific "content" section where the page specific stuff goes. I can't figure out how this is done with XSLT. In the case of this application I have a value available to me in the xml backing the xslt page, lets call it ContentXSL, who's value is the name of the xsl file I want to use for the content section of the page. I know it's not possible but it would be nice to use:

 <xsl:call-template name="{$ContentXSL}" />

然后,我可以简单地说,在内容部分。然而这是不可能的,所以不是我需要一个巨大的选择语句调用的基础上ContentPage变量正确的模板。这也意味着我的布局。 XSL文件,我将不得不包括所有40-50 XSL文件..我想的开销将是pretty的大,但我不知道这一点。这是一个合理的事情,如果该网站获得大量的流量?

Then I could simply put that in the content section.. However this isn't possible, so instead I will need a massive choose statement that calls the correct template based on the ContentPage variable.. This also means in my Layout.xsl file I would have to include all 40-50 xsl documents.. I would think the overhead would be pretty big, but I'm not sure about that. Is this a reasonable thing to do if the site gets a lot of traffic?

什么是这样做的其他常见的方式?这似乎是最现代的框架,允许你使用这个模式来装饰内容。在Symfony的的情况下,它的工作非常出色,是pretty的见灵活(带插槽和所有)。

What are other common ways of doing this? It seems like most modern frameworks allow you to use this pattern to decorate content. In the case of Symfony it worked really well and was pretty flexibile (with slots and all that).

我知道其他可能的解决方案是让所有有类似的标记,包括像页眉和页脚特殊路段40独立的文件。这意味着,如果我想改变我的网站的布局的整体结构我不得不编辑所有40-50页,但(很讨厌)。

I know the other potential solution is to have 40 independant files that all have similar markup and include special sections like the header and footer. This means if I want to change the overall structure of the layout of my site I'd have to edit all 40-50 pages though (very annoying).

更新 - 更多的解释

我想进一步解释这一点,因为我有一定​​的要求这将需要大量的工程变更。 首先,后端是要传递给我一些XML,这将让我知道询问参数都在该网站的网址..此外,它会传递给我,我需要建立在我的网页(数据数据形式的业务数据,没有HTML或类似的东西)的。 数据类似于此:

I want to further explain this because I have certain requirements which would take considerable engineering to change. First of all, the backend is going to pass to me some xml which will let me know of query args are in the URL of the website.. Also, it will pass to me the data I need to build my page (data in the form of business data, no html or anything like that). The data looks similar to this:

<xml>
 <section>Blogs</section>
 <page>showAll</section>
  <data>
   <blogs>
     <blog>
       <author>somebody</author>
       <title></title>
       <content>..</content>
    </blog>
    </blog>..</blog>
   </blogs>    
  </data>
</xml>

现在有什么要的是有一个这样的页面模板:

Now what want is to have a page template like this:

<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:msxsl='urn:schemas-microsoft-com:xslt'>  
 <xsl:output omit-xml-declaration='yes' method='html' media-type='text/html' indent='yes' />
 <xsl:include href="Header.xsl"/>
 <xsl:include href="Nav.xsl"/> 
 <xsl:template name='MainLayout' match='*'>
 <html>
  <head>
   <title></title>
  </head>
  <body>
    <div id="header"><xsl:call-template name="Header" /></div>
    <div id="nav"><xsl:call-template name="Nav" /></div>
    <div id="content">
      [here is where i want to use the xsl from {/xml/section}/{/xml/page}.xsl]
    </div>
  </body>
</html>
</xsl:template>    
</xsl:stylesheet>

现在在本页我将有以下文件的内容: 博客/ showAll.xsl

Now in for the content of this page I would have the following file: Blogs/showAll.xsl

<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:msxsl='urn:schemas-microsoft-com:xslt'>  
      <xsl:output omit-xml-declaration='yes' method='html' media-type='text/html' indent='yes' />
<xsl:template name='Blogs_ShowAll'>
  <div id="blogs-showAll">
   ..iterate over /xml/data/blogs converting to html
  </div>
</xsl:template>
</xsl:stylesheet>

该解决方案迄今为止一直不错,但只有一个人是我能够完全消化(一个其中提到包括所有的XSL文件,并使用XSL:选择要选择正确的)。 我不知道如何将FXSL方法适用于手头的问题。 请注意,我不会反对使用的sitemesh式的做法,我指定的HTML / body标签和所有的孩子,有它取代了我在孩子的主体部分为布局内容格(也,如果有一个在孩子标题标签替换标题标签中的布局 - 类似的东西)

The solutions so far have been good but only one of them was I able to fully digest (the one which mentions including all the xsl files and using a xsl:choose to select the right one). I am not sure how to apply the FXSL method to the problem at hand. Note that I would not be opposed to using a sitemesh type approach which I specify the html/body tags and all that in the child and have it replace what I have in the body section of the child into the layout's content div (also, if there is a title tag in the child replace the title tag in the layout -- stuff like that).

推荐答案

在OP提供了他的问题,更多的细节和这个答案提供了目前所要求的其他解决方案。

The OP has provided additional details of his problem and this answer provides the additional solution that is now requested.

我。这个想法:

这个转变

<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="/">
  <html>
   <xsl:apply-templates select="*/page"/>
  </html>
 </xsl:template>

 <xsl:template match="page[. = 'showAll']">
   <!-- Transform all data to html -->
   <xsl:apply-templates select="../*/blogs" mode="showAll"/>
 </xsl:template>

 <xsl:template match="page[. = 'showBrief']">
   <!-- Transform the data to Summary html -->
      <xsl:apply-templates select="../*/blogs" mode="showBrief"/>
 </xsl:template>

 <xsl:template match="blogs" mode="showAll">
  <h1>All Blogs: </h1>
  <table border="1">
    <xsl:apply-templates mode="showAll"/>
  </table>
 </xsl:template>

 <xsl:template match="blog" mode="showAll">
  <tr>
    <td>Blog of <xsl:value-of select="author"/></td>
    <td><xsl:value-of select="title"/></td>
  </tr>
  <tr>
    <td colspan="2"><xsl:apply-templates select="content/node()" mode="showAll"/></td>
  </tr>
  <xsl:if test="not(position()=last())">
   <tr><td colspan="2">&#xA0;</td></tr>
  </xsl:if>
 </xsl:template>

  <xsl:template match="blogs" mode="showBrief">
  <h1>Blogs Summary: </h1>
  <table border="1">
    <xsl:apply-templates mode="showBrief"/>
  </table>
  </xsl:template>

   <xsl:template match="blog" mode="showBrief">
     <tr>
      <td>
        <xsl:value-of select="concat(author, ': ', title)"/>
      </td>
     </tr>
   </xsl:template>

</xsl:stylesheet>

此XML文档的应用时,(根据所提供的XML文本,但使之成为良好的和较大幅度的):

when applied on this XML document (based on the provided XML text, but making it well-formed and more substantial):

<xml>
 <section>Blogs</section>
 <page>showAll</page>
 <data>
   <blogs>
     <blog>
       <author>John Smith</author>
       <title>All about golden fish</title>
       <content>
       Here I publish my latest achievements
       in raising golden fish.
       </content>
    </blog>
     <blog>
       <author>Mary Jones</author>
       <title>Knitting, Knitting, Knitting</title>
       <content>
       How to knit a sharf.
       </content>
    </blog>
   </blogs>
 </data>
</xml>

产生所需的显示所有类型的输出

<html>
   <h1>All Blogs: </h1>
   <table border="1">
      <tr>
         <td>Blog of John Smith</td>
         <td>All about golden fish</td>
      </tr>
      <tr>
         <td colspan="2">
            Here I publish my latest achievements
                   in raising golden fish.

         </td>
      </tr>
      <tr>
         <td colspan="2">&nbsp;</td>
      </tr>
      <tr>
         <td>Blog of Mary Jones</td>
         <td>Knitting, Knitting, Knitting</td>
      </tr>
      <tr>
         <td colspan="2">
                   How to knit a sharf.

         </td>
      </tr>
   </table>
</html>

现在我们修改XML文档,并与这一个替换元素

Now we change the XML document and replace the page element with this one:

 <page>showBrief</page>

:当相同的变换的施加在所更新的XML文档时,它现在产生所需的输出摘要

When the same transformation is applied on the updated XML document, it now produces the desired summary output:

<html>
   <h1>Blogs Summary: </h1>
   <table border="1">
      <tr>
         <td>John Smith: All about golden fish</td>
      </tr>
      <tr>
         <td>Mary Jones: Knitting, Knitting, Knitting</td>
      </tr>
   </table>
</html>

二。下一步

在实践中在给定模式的所有模板将是在其单独的XSL文件,并将由初级样式表导入:

In practice all templates in a given mode will be in their separate xsl file and will be imported by the primary stylesheet:

变换(主样式表),从而成为

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:import href="showAll.xsl"/>
 <xsl:import href="showBrief.xsl"/>

 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/">
  <html>
   <xsl:apply-templates select="*/page"/>
  </html>
 </xsl:template>
</xsl:stylesheet>

待办事项

的转变提前犯规知道什么模板将被应用 - 转型是完全数据驱动

The transformation doesnt know in advance what templates will be applied -- the transformation is completely data-driven.

不存在,现在可以写,并在未来将应用,而不需要更改主样式表的模板。

Templates that do not exist now can be written in the future and will be applied without the need to change the primary stylesheet.

有没有条件逻辑,&LT; XSL:选择&GT; 的说明等。这是真正的力量在行动XSL模板

这种转变是基于上FXSL是基于同样的想法