【问题标题】:Build an HTML table using XSLT 1.0使用 XSLT 1.0 构建 HTML 表
【发布时间】:2016-08-16 22:25:01
【问题描述】:

我正在为使用 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>

问题在于,preheader 和 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>

【问题讨论】:

    标签: html xml xslt-1.0


    【解决方案1】:

    问题是preheader 和logo 元素是重复的 两次。

    你有这些重复行的原因是这个指令:

    <xsl:apply-templates select="job/surface" /> 
    

    这有效地将模板应用到surface所有 后代,包括您已经处理的preheaderbrand 节点。

    避免这种情况的一种方法是将模板选择性地仅应用于此时需要的节点:

    <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 元素,如我上面的示例所示。

    【讨论】:

    • 我不能使用 colspan 或 rowspan 属性。由于电子邮件客户端的性质,我们必须像我最初的示例一样使用嵌套表。我尝试修改您的解决方案以生成包含嵌套元素的两列表,但无法正确生成嵌套。
    • 恐怕你已经失去了我。如果您不能使用 colspan/rowspan,请忽略我的重写建议。不改xsl:apply-templatesselect表达式就解决了重复行的问题吗?
    • 是的,重复行不再是问题。但我意识到我需要为每个元素应用自定义模板,因为我们需要将样式应用到不同的元素。如果您看到下面的答案,我修改了您的代码以构建正确类型的嵌套表。
    • "我需要为每个元素应用自定义模板" 那么最好坚持你原来的xsl:apply-templates策略,而不是使用xsl:for-each。无论如何,这似乎是另一个问题的话题。
    • 好的。我会修改问题。
    【解决方案2】:

    这是完美的解决方案。它结合了 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>
    

    【讨论】:

      猜你喜欢
      • 2018-06-24
      • 1970-01-01
      • 1970-01-01
      • 2014-12-09
      • 1970-01-01
      • 2012-05-31
      • 1970-01-01
      • 1970-01-01
      • 2019-04-08
      相关资源
      最近更新 更多