我正在为使用XML和XSLT的活动构建HTML电子邮件。我几乎得到了我想要的东西,但是我得到了一些重复的内容,我不知道如何消除重复的元素。
有一个我最初忘记添加的附加要求:我需要为每个内容元素添加自定义模板,以便根据元素应用不同的格式。此外,内容中有一些随机图像需要建模
下面是一些示例XML:
<?xml version="1.0" encoding="UTF-8"?>
<job>
<surface>
<preheader><preheader_p>Click for more information</preheader_p></preheader>
<preheader><preheader_p>Questions? Call 877-555-1212</preheader_p></preheader>
<preheader><preheader_p>Click to unsubscribe</preheader_p></preheader>
<brand href="Images/logo.jpeg" />
<headline>Headline goes here</headline>
<subhead>Subhead goes here</subhead>
<body_copy>First paragraph goes here</body_copy>
<body_copy>Second paragraph goes here</body_copy>
<chart href="Images/graph.jpeg" />
<body_copy>Third paragraph goes here</body_copy>
</surface>
</job>
使用XSLT,我需要构建一个表,将预标题内容插入到两列嵌套表的左列中。在右栏我需要插入产品的标志。
显示预标题和徽标内容后,按顺序插入其余内容,每个内容在各自的表行中。
这是我的XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:output method="html" encoding="UTF-8" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>
<xsl:template match="/">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<table width="600" border="1">
<tr><td>
<table width="100%" border="1">
<tr>
<td width="60%">
<table width="100%" border="1">
<xsl:apply-templates select="job/surface/preheader" />
</table>
</td>
<td width="40%"><xsl:apply-templates select="job/surface/brand"/></td>
</tr>
</table>
</td></tr>
<xsl:apply-templates select="job/surface" />
</table>
</body>
</html>
</xsl:template>
<xsl:template match="preheader"><tr><td style="font-size:11pt;"><xsl:value-of select="."/></td></tr>
</xsl:template>
<xsl:template match="brand"><img style="max-width:100%" src="{@href}" />
</xsl:template>
<xsl:template match="headline"><tr><td style="font-size:20pt;"><xsl:value-of select="."/></td></tr>
</xsl:template>
<xsl:template match="subhead"><tr><td style="font-size:16pt;"><xsl:value-of select="."/></td></tr>
</xsl:template>
<xsl:template match="body_copy"><tr><td style="font-size:12pt;"><xsl:value-of select="."/></td></tr>
</xsl:stylesheet>
问题是标题和logo元素重复了两次。
目标是创建以下HTML:<html>
<body>
<table width="600" border="1">
<tr><td>
<table width="100%" border="1">
<tr><td width="60%"><table width="100%" border="1">
<tr><td>Click for more information</td></tr>
<tr><td>Questions? Call 877-555-1212</td></tr>
<tr><td>Click to unsubscribe</td></tr>
</table></td>
<td width="40%"><img style="max-width:100%" src="Images/logo.jpeg"></td</tr>
</table></td></tr>
<tr><td style="font-size:20pt;">Headline goes here</td></tr>
<tr><td style="font-size:16pt;">Subhead goes here</td></tr>
<tr><td style="font-size:12pt;">First paragraph goes here</td></tr>
<tr><td style="font-size:12pt;">Second paragraph goes here</td></tr>
<tr><td><img style="max-width:100%" src="Images/graph.jpeg" /></td></tr>
<tr><td style="font-size:12pt;">Third paragraph goes here</td></tr>
</table>
</body>
</html>
问题是标题和徽标元素重复两次。
你有这些重复行的原因是:
<xsl:apply-templates select="job/surface" />
这有效地将模板应用于所有 surface
的后代-包括您已经处理过的preheader
和brand
节点。
<xsl:apply-templates select="job/surface/headline | job/surface/subhead | job/surface/body_copy" />
顺便说一句,我想知道你是否能简单地说:
XSLT 1.0<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/1999/xhtml">
<xsl:output method="xml" encoding="UTF-8" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" indent="yes"/>
<xsl:template match="/job">
<html>
<body>
<table border="1">
<tr>
<td>
<xsl:value-of select="surface/preheader[1]"/>
</td>
<td rowspan="{count(surface/preheader)}">
<img style="max-width:100%" src="{@href}" />
</td>
</tr>
<xsl:for-each select="surface/preheader[position() > 1]">
<tr>
<td>
<xsl:value-of select="."/>
</td>
</tr>
</xsl:for-each>
<xsl:for-each select="surface/headline | surface/subhead | surface/body_copy">
<tr>
<td colspan="2">
<xsl:value-of select="."/>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
还要注意,您在其他模板中创建的元素不会继承您的名称空间声明。您可以看到许多表行位于无名称空间中:
<tr xmlns="">
您应该将默认名称空间声明移动到stylesheet
元素,如上面的示例所示。
这是一个完美的解决方案。它结合了Michael对重复元素的修复,并提供了模板应用程序来格式化单个内容元素。由于
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml">
<xsl:output method="xml" encoding="UTF-8" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" indent="yes"/>
<xsl:template match="/job/surface">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Untitled Document</title>
</head>
<body>
<table width="600" border="0" align="center" style="font-family:Arial, Helvetica, sans-serif;">
<tr><td><table width="100%"><tr><td width="60%" valign="bottom">
<table width="100%"><tr><td style="padding: 0px 0px 5px 0px; font-size:10px;"><xsl:value-of select="preheader[1]"/></td></tr>
<xsl:for-each select="preheader[position() > 1]">
<tr><td style="padding: 0px 0px 5px 0px; font-size:10px;"><xsl:value-of select="."/></td></tr></xsl:for-each>
</table></td>
<td width="40%"><xsl:apply-templates select="brand"/></td></tr></table></td></tr>
<xsl:apply-templates select="headline | subhead | bullet_level_1 | bullet_level_2 | body_copy | footnote | chart | logo | generic_image"/>
</table>
</body>
</html>
</xsl:template>
<!--Add templates below to style each element...-->
<xsl:template match="headline"><tr><td class="headline full" valign="top" style=" font-size:150%; font-weight:bold; color:#444444; padding-bottom:5px; padding-top:14px;"><xsl:apply-templates /></td></tr></xsl:template>
<xsl:template match="subhead"><tr><td class="subhead" style="padding: 5px 0px 0px 0px; color: rgb(181,26,138); font-size: 115%;"><xsl:apply-templates /></td></tr></xsl:template>
...
</xsl:stylesheet>