我在探索XML - > XSLT - > HTML meme用于生成Web内容。我的XSLT经验非常少。
我很好奇XSLT中有哪些机制可用于处理抽象或“重构”。
例如,对于通用HTML和服务端包含,可以将许多页面模板化并分解为常见页眉,导航和页脚段,而页面本身基本上就是正文。
常见的标记语言,JSP,PHP,ASP,允许所有这些段都具有动态内容(例如将用户名添加到每个标题块)。
JSP通过允许您创建标记文件甚至更远,它可以接受在生成内容时使用的参数,甚至可以在标记内部包围和处理内容。
我很好奇在XSLT中完成了类似的功能。有什么设施可以为创建HTML页面等事情制作可重复使用的XSLT块?
答案 0 :(得分:14)
对于我自己的项目,这就是我分页的方式。有一个导入的template.xsl文件 由我的每个XSL。大多数页面只有template.xsl,但有些页面如cart等需要自己的 因为他们正在解析不同类型的数据。
<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扩展。请注意,这是必需的,因为如果a 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>
对我来说它非常漂亮。如果有任何问题我可以为您解答,请告诉我。
答案 1 :(得分:5)
答案 2 :(得分:2)
您可以使用xsl Include和Import语句抽象出部分页面。 XSLT本身就是可以重现标记文件类型行为的东西。使用所需的标记编辑xml数据文件。同时,你的xsl模板将知道如何处理这些标签然后他们会遇到它们。
答案 3 :(得分:2)
您可以提供模板名称,然后通过“call-template”
进行调用在XSLT 2.0中,您可以创建自己的函数(虽然我发现语法曲折)
一个值得探索的好地方是使用XSLT生成XSLT样式表。这使您可以自动执行常见的转换方案,其中90%的样式表是样板文件。为此,您需要熟悉'namespace-alias'。它是扩展您的语言知识的好方法。
答案 4 :(得分:2)
XSL基于基于进行模板化。
XML数据可以在三个级别“重复使用”。在最基本的级别,您可以<xsl:for-each />
通过XML。
注意:For-each在XSL中没有循环遍历数据,它只是匹配数据。此外,当你的“内部”为每个你的内部那个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>
注意:为了使Match模板起作用,它所匹配的XML Node需要存在。如果不匹配,则模板不被调用。
命名模板的示例
<xsl:template name="WriteOut">
... data with NO Context Here ...
</xsl:template>
或者从匹配的模板中调用命名模板
<xsl:template match="/">
<xsl:call-template name="WriteOut" />
<xsl:template>
注意:您可以混合和匹配调用匹配和命名模板的位置,您只需要查看您所处的上下文。
所有模板节点都保存在 XSL样式表中,您可以包含和导入各种样式表。例如,您可以在一个模板中保存处理HTML标头节点的所有模板,并在另一个模板中保存处理HTML主体节点的所有模板。然后,您可以创建一个包含Header和Body样式表的样式表。
包含节点的示例
<xsl:include href="header.xsl" />
总之,有三种方法可以抽象数据块,通过for-eaching,模板化或通过包含样式表。
答案 5 :(得分:1)
XSLT功能强大,但它与大多数编程语言非常不同,它对你提供的内容非常有限,所以你用另一种语言内置的东西可能需要一些相当复杂的xsl操作来处理。我发现the cheatsheet from here在我几周前经历了大量的XSLT工作时很有用。
不要指望XSLT会以特定的方式做事情,你可能会找到做这些事情的好方法,但是如果你对某些事情应该如何运作有太多的了解,那很容易被卡住。 / p>