在代码中构建HTML的技术

时间:2008-12-17 20:22:45

标签: html language-agnostic code-generation

将html模板作为资源编译到应用程序中。 HTML模板的片段如下所示:

<A href="%PANELLINK%" target="_blank">
   <IMG border="0" src="%PANELIMAGE%" style="%IMAGESTYLE%">
</A><BR>
%CAPTIONTEXT%

我喜欢这样,因为较大的资源HTML文件包含样式,非怪癖模式等。

但总是如此,他们现在想要在没有链接时应该省略Anchor标签的选项。如果没有标题,则应省略BR标记。


考虑技术Nº1

鉴于我不想在C#代码中构建完整的HTML片段,我认为类似于:

%ANCHORSTARTTAGPREFIX%<A href="%PANELLINK%" target="_blank">%ANCHORSTARTTAGPOSTFIX%
   <IMG border="0" src="%PANELIMAGE%" style="%IMAGESTYLE%">
%ANCHORENDTAGPREFIX%</A>%ANCHORENDTAGPOSTFIX%CAPTIONPREFIX%<BR>
%CAPTIONTEXT%%CAPTIONPOSTFIX%

认为我可以使用前缀和后缀将HTML代码转换为:

<!--<A href="%PANELLINK%" target="_blank">-->
   <IMG border="0" src="%PANELIMAGE%" style="%IMAGESTYLE%">
<!--</A>--><!--<BR>
%CAPTIONTEXT%-->

但这只是荒谬的,加上一个回答者提醒我们它浪费了带宽,并且可能是错误的。


考虑技术Nº2

批发替换标签:

%AnchorStartTag%
   <IMG border="0" src="%PANELIMAGE%" style="%IMAGESTYLE%">
%AnchorEndTag%%CaptionStuff%

并执行find-replace以更改

%AnchorStartTag%

"<A href=\"foo\" target=\"blank\""

考虑技术Nº3

我考虑过为重要的HTML元素提供ID:

<A id="anchor" href="%PANELLINK%" target="_blank">
   <IMG border="0" src="%PANELIMAGE%" style="%IMAGESTYLE%">
</A><BR id="captionBreak">
%CAPTIONTEXT%

然后使用HTML DOM解析器以编程方式删除节点。但是没有简单的方法可以访问值得信赖的HTML DOM解析器。如果HTML是xhtml,我将使用各种内置/本机可用的xml DOM解析器。


考虑技术Nº4

到目前为止我实际拥有的是:

private const String htmlEmptyTemplate = 
    @"<!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.01//EN\"""+Environment.NewLine+
    @"   ""http://www.w3.org/TR/html4/strict.dtd"">"+Environment.NewLine+
    @"<HTML>"+Environment.NewLine+
    @"<HEAD>"+Environment.NewLine+
    @"  <TITLE>New Document</TITLE>"+Environment.NewLine+
    @"  <META http-equiv=""X-UA-Compatible"" content=""IE=edge"">"""+Environment.NewLine+
    @"  <META http-equiv=""Content-Type"" content=""text/html; charset=UTF-8"">"+Environment.NewLine+
    @"</HEAD>"+Environment.NewLine+
    @""+Environment.NewLine+
    @"<BODY style=""margin: 0 auto"">"+Environment.NewLine+
    @"  <DIV style=""text-align:center;"">"+Environment.NewLine+
    @"      %ContentArea%"+Environment.NewLine+
    @"  </DIV>" + Environment.NewLine +
    @"</BODY>" + Environment.NewLine +
    @"</HTML>";

private const String htmlAnchorStartTag = 
    @"<A href=""%PANELLINK%"" target=""_blank"">";

//Image is forbidden from having end tag
private const String htmlImageTag = 
    @"<IMG border=""0"" src=""%PANELIMAGE%"" style=""%IMAGESTYLE%"">";

private const String htmlCaptionArea =
    @"<BR>%CAPTIONTEXT%";

我已经想要挖出我的眼球了。在代码中构建HTML是一场噩梦。写作是一场噩梦,调试的噩梦和维持的噩梦 - 这会让下一个人感到困难。我希望有另一个解决方案 - 因为我下一个人。

6 个答案:

答案 0 :(得分:11)

我在这个游戏中的声望已经很低,这让我可以自由地告诉你,你,先生或女士,非常需要XSLT。如果失败了(你可能会),你需要在VB.NET中查看XML literals(它为你提供了你正在寻找的基于模板的解决方案......)。由于我更喜欢​​留在C#中(即使我是在VBA上出生并长大的),我使用的是XSLT。

我的两个不受欢迎的建议都要求使用XHTML而不是HTML。仅此要求对许多传统开发人员来说是一个很大的转折点。我已经可以通过使用大写字母来查看HTML元素了,你会发现我的评论完全没用。所以我现在应该停止写作。

答案 1 :(得分:2)

如何:将XML存储为您的片段:

<fragment type="link_img_caption">
  <link href="%PANELLINK%" />
  <img src="%PANELIMAGE%" style="%IMAGESTYLE%" />
  <caption text="%CAPTIONTEXT%" />
</fragment>

拉出来,用“真正的”字符串替换占位符(当然,你已经仔细地将XML转义),

...并使用简单的XML转换来生成HTML输出:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html" version="4.0" encoding="iso-8859-1" indent="yes"/>

  <xsl:template match="/">
    <xsl:apply-templates select="fragment" />
  </xsl:template>

  <xsl:template match="fragment[@type = 'link_img_caption']">
    <xsl:choose>
      <xsl:when test="link[@href != '']">
        <a href="{link/@href}" target="_blank">
          <img src="{img/@src}" style="{img/@style}" border="0" />
        </a>
      </xsl:when>
      <xsl:otherwise>
        <img src="{img/@src}" style="{img/@style}" border="0" />
      </xsl:otherwise>
    </xsl:choose>
    <xsl:if test="caption[@text !='']">
      <br />
      <xsl:value-of select="caption/@text" />
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>

由于type属性,可以添加其他片段类型。有很大的空间来改进这一点,因此请将其视为可以完成的示例。

输出:

<a href="%PANELLINK%" target="_blank">
  <img src="%PANELIMAGE%" style="%IMAGESTYLE%" border="0">
</a>
<br>
%CAPTIONTEXT%

并且,如果XML中的链接href为空:

<img src="%PANELIMAGE%" style="%IMAGESTYLE%" border="0">
<br>
%CAPTIONTEXT%

答案 2 :(得分:2)

使用模板引擎,例如these之一。

答案 3 :(得分:0)

1。)不要使用评论,你会向浏览器发送无用的数据,浪费带宽并遇到BUGs in IE

2。)这会不会像某种方法那样更好? (我不熟悉C#)但这样的事情对我来说更有意义。

//using PHP in this example
function HTMLImage($imageData, $linkData){
  var str = '';
  //if there is link data, start <a> tag
  $str .= '<a '.{expand any attributes}.'>';

  //add image tag and attributes from $imageData
  $str .= '<img '.{expand any attributes}.'/>';

  //if there is link data, close <a> tag
  $str .= '</a>';
  return $str;
}

答案 4 :(得分:0)

我会使用Template Toolkit,但遗憾的是,它目前仅在PerlPython中实施。

test.pl

use Template;

my $template = Template->new({
  VARIABLES => {
    ImageStyle  => "default",
    CaptionText => "Place Caption Here"
  },
});

$template->process( 'test.tt', {
    panel => {
      link  => "http://Stackoverflow.com/",
      image => "/Content/Img/stackoverflow-logo-250.png",
      alt   => "logo link to homepage"
    }
} );

test.tt


[% IF panel.link -%]
<A href="[% panel.link %]" alt="[% panel.alt %]" target="_blank">
[%- END -%]

[%- IF panel.image -%]
   <IMG border="0" src="[% panel.image %]" style="[% ImageStyle %]">
[%- END -%]

[%- IF panel.link %]</A>[% END %]<BR>
[% CaptionText %]

输出:

<A href="http://Stackoverflow.com/" alt="logo link to homepage" target="_blank">
   <IMG border="0" src="/Content/Img/stackoverflow-logo-250.png" style="default">
</A><BR>
Place Caption Here

如果未定义变量panel.link,则会跳过锚标记。

   <IMG border="0" src="/Content/Img/stackoverflow-logo-250.png" style="default">
<BR>
Place Caption Here

答案 5 :(得分:0)

模板是一种严重的代码味道。看看Seaside如何生成html。

[编辑]另一个人没有线索投票。