我使用XSL模板作为Web框架的网页模板,最终输出为XHTML 1.0 Strict;它需要XML输入并输出XHTML。它完美地工作除了一个问题 - 结束输出也输出XML节点而不仅仅是内容。这是基本的XML(缺少一些项目,但总体设计是相同的):
<Page>
<PageScript>
<Script>./js/myscript.js</Script>
</PageScript>
<PageCSS>
<CSS>./css/mycss.css</CSS>
</PageCSS>
<PageContent>Blah blah blah</PageContent>
</Page>
这是XSL模板
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:response="http://www.ntforl.com/"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:lang="en">
<xsl:output
method="xml"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
/>
<xsl:template match="//PageCSS">
<xsl:for-each select="CSS">
<link type="text/css" rel="stylesheet">
<xsl:attribute name="href">
<xsl:value-of select="." />
</xsl:attribute>
</link>
</xsl:for-each>
</xsl:template>
<xsl:template match="//PageScript">
<xsl:for-each select="Script">
<script type="text/javascript">
<xsl:attribute name="src">
<xsl:value-of select="." />
</xsl:attribute>
</script>
</xsl:for-each>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="/" disable-output-escaping="yes">
<html>
<head>
<title>
<xsl:value-of select="//PageTitle" />
</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<link type="text/css" rel="stylesheet" href="template/style/globalStyle.css" />
<link type="text/css" rel="stylesheet" href="template/style/standards.css" />
<xsl:apply-templates select="//PageCSS" />
<script type="text/javascript" src="template/js/some_file.js"></script>
<xsl:apply-templates select="//PageScript" />
</head>
<body onload="">
<div id="container">
<div id="top">
<div class="clear" />
</div>
<div id="main">
<div class="left" style="width: 708px; margin-top: 10px;">
<h1 class="center">
<xsl:value-of select="//PageTitle" />
</h1>
</div>
<div class="clear" />
<div id="rightPane">
<div id="rightPaneContent">
<xsl:apply-templates select="//PageContent" />
</div>
<img src="template/images/mainBgBottom.png" alt="" />
</div>
</div>
</div>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
问题在于PageContent,它只发生在PageContent上。运行转换时,模板输出
<PageContent xmlns=""> node content </PageContent>
在XHTML中。我需要知道如何摆脱它,以便我可以拥有一个有效的XHTML 1.0 Strict文档。
奇怪的是,PageContent节点是唯一执行此操作的节点,没有其他节点获取包含输出中节点名称的内容。这种行为的原因是什么?
答案 0 :(得分:3)
您在apply-templates
节点上呼叫PageContent
:
<xsl:apply-templates select="//PageContent" />
与此匹配的唯一模板是此模板,因此PageContent
节点被复制:
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
可能你应该添加另一个匹配PageContent
的模板,只处理子节点,而不复制PageContent
本身:
<xsl:template match="//PageContent">
<xsl:apply-templates/>
</xsl:template>
答案 1 :(得分:2)
我会尝试将<xsl:apply-templates select="//PageContent" />
替换为:
<xsl:apply-templates select="//PageContent/node()" />
答案 2 :(得分:2)
正如@sth和@molf已经指出的那样,您将获得由您的身份模板(<xsl:template match="@*|node()">
)复制的节点,因为样式表中没有其他模板与<PageContent>
个节点匹配。
作为其他两个解决方案已经提供的解决方案的替代方案,您可以将身份模板更改为:
<xsl:template match="@*|node()[not(self::PageContent)]">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
现在遇到<PageContent>
时,身份模板不再匹配。将使用隐式的元素默认模板,即:
<xsl:template match="*">
<xsl:apply-templates />
</xsl:template>
这意味着模板将自动应用于<PageContent>
个孩子,而本身节点不会被复制 - 只是你想要的。