10

我正在探索 XML -> XSLT -> HTML meme 以生成 Web 内容。我的 XSLT 经验很少。

我很好奇 XSLT 中有哪些机制可用于处理抽象或“重构”。

例如,使用通用 HTML 和服务端包含,可以将许多页面模板化并分解到有公共页眉、导航和页脚段的地方,而页面本身基本上就是正文。

常见的标记语言 JSP、PHP、ASP 甚至允许所有这些段具有动态内容(例如将用户名添加到每个标题块)。

JSP 更进一步,它允许您创建标记文件,这些文件可以接受生成内容时要使用的参数,甚至可以在标记本身内包围和处理内容。

我很好奇类似的功能是在 XSLT 中完成的。有哪些工具可以为创建 HTML 页面之类的事情制作可重用的 XSLT 块?

4

6 回答 6

14

对于我自己的项目,这就是我划分页面的方式。我的每个 XSL 都导入了一个 template.xsl 文件。大多数页面只有 template.xsl,但有些页面(如购物车等)需要自己的,因为它们解析的数据类型不同。

<page title="Home">
    <navigation>
        <!-- something here -->
    </navigation>
    <main>
        <!-- something here -->
    </main>
</page>

这是我的 template.xsl 中的一个片段。我把所有常见的东西都扔在这里,然后让我的页面有机会通过call-template.

<xsl:template match="/page" name="page">  
    <html>
    <head>  
        <title><xsl:value-of select="(@title)" /></title>           
        <xsl:call-template name="css" />
        <xsl:call-template name="script" />
    </head>
    <body>
        <xsl:call-template name="container" />
    </body>
    </html>
</xsl:template>

我的 css 标签如何响应的示例。请注意,它调用css-extended.的 css 仅具有适用于所有页面的通用 css'。有些页面需要更多。那些可以覆盖css-extended。请注意,这是必需的,因为call-template如果页面调用模板但未在任何地方定义它,则会失败。

   <xsl:template name="css">
        <link rel="stylesheet" type="text/css" href="{$cssPath}reset.css"  />
        <link rel="stylesheet" type="text/css" href="{$cssPath}style.css"  />
        <link rel="stylesheet" type="text/css" href="{$cssPath}layout.css" />
        <xsl:call-template name="css-extended" />
    </xsl:template>   

    <!-- This is meant to be blank. It gets overriden by implementing stylesheets -->
    <xsl:template name="css-extended" />

我的容器将以类似的方式工作——定义了常见的东西,然后每个页面都可以提供一个实现。默认实现是在 XSL 中。(在content

  <xsl:template name="container">
        <div id="container">
            <xsl:call-template name="header" />
            <xsl:call-template name="content" />
            <xsl:call-template name="footer" />
        </div>
    </xsl:template>  

    <xsl:template name="content">
        <div id="content">
            <div id="content-inner">
                <xsl:call-template name="sideBar" />
                <xsl:call-template name="main" />
            </div>
        </div>
    </xsl:template>   

    <xsl:template name="main">
        <div id="main">
            <xsl:apply-templates select="main" />
            <xsl:call-template name="main-extended" />
       </div>
    </xsl:template>

    <!-- This is meant to be blank. It gets overriden by implementing stylesheets -->
    <xsl:template name="main-extended" />

<xsl:template name="footer">
        <div id="footer">
        <div id="footer-inner">
        <!-- Footer content here -->
        </div>
        </div>
</xsl:template>  

它对我来说非常漂亮。如果有任何问题我可以为您解答,请告诉我。

于 2008-10-03T15:53:06.437 回答
5

模板,包括。

Xsl 与任何其他编程语言都非常不同。Its rule based.

我建议您阅读有关Xslt的内容,然后再问一些更具体的问题。

于 2008-10-03T15:37:53.083 回答
2

您可以使用 xsl Include 和 Import 语句来抽象出页面的某些部分。XSLT 本身就是那种可以重现标签文件类型行为的东西。您可以使用所需的标签编辑 xml 数据文件。同时,您的 xsl 模板将知道如何处理这些标签然后遇到它们。

于 2008-10-03T15:44:30.917 回答
2

您可以给模板名称,然后通过'call-template'调用它们

在 XSLT 2.0 中,您可以创建自己的函数(尽管我发现语法很曲折)

一个很好的探索领域是使用 XSLT 生成 XSLT 样式表。这使您可以自动化常见的转换场景,其中 90% 的样式表是样板。为此,您需要熟悉“命名空间别名”。这是扩展您的语言知识的好方法。

于 2008-10-03T15:51:25.660 回答
2

XSL基于模板。

XML 数据可以在三个级别上“重用”。在最基本的层面上,您可以<xsl:for-each />通过 XML。

注意:XSL 中的 for-each 不是循环遍历数据,它只是匹配数据。同样,当您的“内部”为每个您的内部 XML 的“上下文”时(这就像编程中的“范围”概念)

使用和重用 for-each 的示例

<xsl:for-each select="/xml/data/here">
    ... do some stuff ...
</xsl:for-each>
<xsl:for-each select="/xml/data/here">
    ... do some DIFFERENT stuff ...
</xsl:for-each>

for-each 节点包含在模板节点中(第二级重用)。有两种类型的模板节点:匹配和命名。匹配模板节点,作用类似于上面提到的 for-each 节点,但如果在 XSL 处理开始时匹配到任何节点,模板引擎会自动调用该节点。匹配模板节点也可以显式应用。另一方面,命名模板节点总是被显式应用,并且可以被认为是类似的函数。

始终调用的匹配模板示例(因为根节点将始终存在)

<xsl:template match="/">
    ... do some stuff ...
</xsl:template>

一个匹配模板显式调用另一个匹配模板

<xsl:template match="/">
    <xsl:apply-templates select="xml/data/too" />
</xsl:template>

<xsl:template match="xml/data/too">
     ... do something ...
</xsl:template>

注意:为了使匹配模板工作,它匹配的 XML 节点需要存在。如果不匹配,则不调用该模板。

命名模板示例

<xsl:template name="WriteOut">
    ... data with NO Context Here ...
</xsl:template>

或从匹配的模板调用命名模板

<xsl:template match="/">
   <xsl:call-template name="WriteOut" />
<xsl:template>

注意:你可以在调用匹配和命名模板的地方混合和匹配,你只需要注意你所处的上下文。

所有模板节点都保存在XSL Stylesheets中,您可以包含导入各种样式表。例如,您可以将处理 HTML 标头节点的所有模板保存在一个模板中,并将处理 HTML 正文节点的所有模板保存在另一个模板中。然后,您可以创建一个包含 Header 和 Body 样式表的样式表。

包含节点的示例

<xsl:include href="header.xsl" />

总之,有三种方法可以抽象数据块,通过 for-eaching、通过模板或通过包含样式表。

于 2008-10-05T12:50:43.497 回答
1

XSLT 功能强大,但它与大多数编程语言有很大不同,它为您提供的功能非常有限,因此您使用另一种语言内置的东西可能需要一些非常复杂的 xsl 操作才能使用。几周前,当我进行大量 XSLT 工作时,我发现这里的备忘单很有用。

不要期望 XSLT 会以特定的方式做事,您可能会找到做这些事的好方法,但是如果您对某事应该如何工作有太多固定的想法,那么很容易陷入困境。

于 2008-10-03T16:21:12.870 回答