Thinking XML: XML 样式的 HTML5

时间:2015-08-08

有一段时间,在 web 上出现了有关标记未来发展的竞争,即 W3C 的 XHTML 2 和 HTML5 之间的竞争,这是主要浏览器厂商在其各自组织下进行的竞争。首先,W3C 接管了 HTML5,并且它最近宣布了 XHTML 2 的衰退。这就使 web 上的 XML 的未来产生了巨大差异,此外, HTML5 现已成为每个 XML 开发人员都会使用的一种技术。

  但是,XML 爱好者不必失望:HTML5 支持恰当的 XML 序列化。了解 XML 形式的 HTML5 包括与旧式 XHTML 规则的一些主要差别,以及如何在现代 web 浏览器中实际应用此词汇。

  HTML 的历史一直存有争议。即使是 web 架构师尽了最大努力,网页始终是一个难以驾驭的领域,它具有混乱的、令人费解的,甚至是有时非常恼人的破碎标记(别名为标签杂烩)。 XML 的一个目标始终是帮助解决这种混乱问题,因此 XML 被定义为 “web 的 SGML”(SGML 是一种原语言,而 HTML 只是其中的一种)。XML 一问世就立刻引起了轩然大波。W3C 期望 XML 在浏览器中获得成功,并将 XHTML 作为比 HTML 更连贯的最自然的发展。不幸的是,总是出现意想不到的问题破坏这一目标。看似简单的概念(比如命名空间和链接)成为技术政治的梦魇。由此产生的争议和延迟已足以使浏览器开发人员确信,XML 可帮助解决现有问题,但是它又提出了更多新的、未知的问题。

  即使没有越来越多的证据表明 XML 并非灵丹妙药,对于使用标记杂烩的大量旧式网页来说,当浏览器开发人员试图迁移到严格的基于 XML 的路径时,总是会遇到问题。此外,请考虑 Postel's Law(Postel 法则),这一法则根据着名的计算机科学家 John Postel 命名。该法则规定:

  像保守派那样去做,像自由派那样去接受其他的。

  XML 的限制与此法则在服务器或数据库端是一致的,管理人员在策略方面是保守的。这也是 XML 茁壮成长的原因。web 浏览器可能是从其他人那里接收信息的最终示例,所以这也是 XML 和 Postel 法则最关注的地方。

  XHTML 的发展

  在过去几年里形势已非常严峻。浏览器厂商在很大程度上一直忽略了 W3C,并且成立了一个 Web 超文本应用技术工作组(Web Hypertext Application Technology Working Group,WHAT WG)发展 HTML,创建了 HTML5。但是对 W3C XHTML 的支持却停滞了。通过提供场所来继续 HTML5 工作,W3C 第一次认清了现实,并且它在 2009 年停止了 XHTML 工作,接受了失败这一事实。没有一种方法来衡量这是否是 XHTML 在实践中的结束。当然 HTML5 并非是有意设计为 XML 友好的,但它至少以 HTML 的 XML 序列化形式(在本文中是 XHTML5)提供了口惠。然而,事情还远没有解决,正如 HTML5 FAQ 中的一个问题所述:

  如果我在 HTML 文档中小心地使用语法,是否可以使用 XML 解析器处理它?不可以。HTML 和 XML 有着显着的差别,尤其是在解析需求方面,并且您无法使用针对一方设计的工具去处理另一方的问题。但是,由于 HTML5 是根据 DOM 定义的,所以在大多数情况下,可使用 HTML 或 XHTML 序列化来表示同一文档。但是,稍后将介绍一些差异,这些差异使 XHTML 无法准确表示一些 HTML 文档,反之亦然。

  对于对 web 上的 XML 的未来感兴趣的任何开发人员来说,这种情况会让他们感到非常困惑。本文将提供一个实用指南,阐述在 HTML 5 中使用 XML 的情况。本文是为那些被我称为终极网络黑客 的人而编写的,他们不是 W3C 标准大师,但要么对在 web 上生成 XHTML 5 感兴趣,要么对以简单的方式使用它感兴趣(也就是使用信息而不是担心庞大复杂的呈现)。我承认,做出其中一些建议对我来说是痛苦的,因为正确处理 XML 已有一个长期主张。记住,HTML5 仍然是 W3C 的工作草案,在它成为一个完整的建议之前可能还需要一段时间。尽管其中一些特性很稳定且能在 web 上很好地实现。

  将文档作为 XHTML5 提供

  不幸的是,我有更多的坏消息。您可能无法像官方定义的那样使用 XHTML5。这是因为一些法规规定:为了将文档转换为 XHTML5,它必须使用 application/xhtml+xml 或 application/xml MIME 类型提供。但是如果您这样做,所有发行的 Microsoft? Internet Explorer? 版本都将无法显示它(但使用其他主流的现代浏览器则没有问题)。惟一实用的解决方法是使用 text/html MIME 类型提供语法 XHTML5。从技术上讲,这可能违反了一些版本的 HTML5 规范,但是除非您可以不支持 Internet Explorer,否则就没有更多的选择。说到增加混乱,这在相关的工作组中是一个非常有争议的话题,并且至少这种语言已缓和了一些草案。 Internet Explorer 9 测试版(也称为 “平台预览”)完全支持使用 XML MIME 类型提供的 XHTML,所以一旦用户可普遍使用此版本时,此问题就不存在了。同时,如果您需要支持 Internet Explorer 6 或更早的版本,则本文中介绍的解决方法就不够用了。您就只能使用 HTML 4.x 了。

  对终极 web 黑客的建议:使用 text/html MIME 类型提供语法 XHTML5。

  DOCTYPE 的乐趣

  从终极 web 黑客的角度来说,一个好消息是,XHTML5 使文档类型声明(DTDecl)问题变得更少。XHTML 1.x 和 2 需要臭名昭着的构造,比如 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">。这样做的最大问题是新型的处理器很可能加载此 DTD URL,而这可能是一种不必要的网络操作。此外,一个 URL 包括许多其他 URL,并且您通常不需要从 W3C 站点下载多个文件。有时 W3C 上放置的文件甚至会有一些问题,这会导致一些很难调试的问题。

  在 XHTML5 中,文件的 XML 性质完全由 MIME 类型决定,并且实际上任何 DTDecl 都会被忽略,所以您可以忽略它。但是 HTML5 提供了最小化的 DTDecl <!DOCTYPE html>。如果您使用此 DTDecl,那么几乎所有浏览器都会切换到 “标准” 模式,即使是完整的 HTML5,这通常更一致且更可预测。注意,HTML5 DTDecl 不会引用任何单个文件,所以可避免早期的一些 XHTML 问题。

  对终极 web 黑客的建议:在 XHTML5 中使用 HTML 最小化的文档类型声明 <!DOCTYPE html> 。

  由于您不使用任何外部 DTD 组件,因此您无法使用常见的 HTML 实体,比如 &nbsp; 或 &copy;。这些都是在那些您未声明的 XHTML DTD 中定义的。如果您想使用它们,XML 处理器将失败并出现一个 undefined entity 错误。惟一安全的命名字符实体是:&lt;、&gt;、&amp;、&quot; 和 &apos;。使用数值等效代替。例如,使用 &#160; 而不是 &nbsp;;使用 &#169; 而不是 &copy;。

  对终极 web 黑客的建议:不要使用任何命名字符实体,以下实体除外:&lt;、&gt;、&amp;、&quot; 和 &apos;

  从技术上讲,如果您将文档作为 text/html 提供,根据第一个建议,使用 HTML 命名字符实体,在大多数浏览器上都不会出错,但是依靠这一意外是非常脆弱的。此外,记住,浏览器并不是 XML 的惟一使用者。其他 XML 处理器被此类文档弄得不知如何是好。

  命名空间的乐趣

  认识 XML 格式的复杂机制的最后一层是命名空间,前两个是 MIME 类型和 DTDecl。可能您过去经常使用类似下列行的内容开始 XHTML 文档。

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" > 

  黑体部分(xmlns="http://www.w3.org/1999/xhtml")是命名空间。在 XHTML5 中,此命名空间仍然是必需的。如果您包含了其他 XML 词汇,比如可缩放的向量图形(Scalable Vector Graphics,SVG),则将他们放置在其各自的必需命名空间中。

  对终极 web 黑客的建议:在 XHTML5 文档的顶部始终包含默认的命名空间,并为其他嵌入的 XML 格式使用相应的命名空间。

  如果您包含了其他词汇,则他们的命名空间声明必须在嵌入部分最外面的开始标记中。如果您在 html 元素中声明了它们,则会遇到一个 text/html 文档一致性错误。

  处理 XHTML5 内容

  XHTML5 支持您使用以下方式指定介质类型:用协议头,比如 HTTP Content-Type 头;使用名为 “字节顺序标记 (BOM)” 的特殊字符标记,或者是使用 XML 声明。只要不互相冲突,您可以随意组合使用这些方法,但避免问题的最好方式是在选择组合方法时要谨慎。不幸的是,使用 XML 声明存在潜在问题,因为它会使 Internet Explorer 8 及更早版本都切换到怪异模式,这会导致臭名昭着的显示异常,也正是因为这种情况才使浏览器闻名于世。

  对终极 web 黑客的建议:对 XHTML5 文档仅使用 Unicode 编码。在文档的开头部分,省略 XML 声明,并使用 UTF-8 编码,或者使用 UTF-16 Unicode 字节顺序标记(Byte Order Mark,BOM)。如果可以,可在提供文档时使用 Content-Type HTTP 头。

  下面是此类 HTTP 头的一个示例:

Content-Type: "text/html; charset=UTF-8" 

  新的语义标记元素

  HTML5 引入了一些新元素,提供语义更明确的内容结构,比如 section 和 article。这些元素是 HTML5 的一部分,可能会发生变化,但是变化不会太大,并且这些新元素提供的改进表达式也降低了风险。一个问题是 Internet Explorer 不是在 DOM 中构造这些元素,所以如果使用 JavaScript,您就需要采用另一个解决方法。Remy Sharp 通过在文档头包含下列代码段来维护 JavaScript 修复。

<!--[if IE]> 
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> 
<![endif]--> 

  您还可能需要定义元素的 CSS 规则,以免任何浏览器以 HTML 4 形式显示文档,HTML 4 形式以内联呈现方式显示未知元素。下列 CSS 应该有效。

header, footer, nav, section, article, figure, aside { 
  display:block; 
} 

  对终极 web 黑客的建议: 使用新 HTML5 元素,但是请包含 HTML5 shiv JavaScript 和默认 CSS 规则以支持它们。

  将它们组合起来

  我已经给出了许多单独的建议,我将把它们组合起来形成一个完整的示例。清单 1 是满足这些建议的 XHTML5。通过 HTTP 提供它时,除非您可以不支持 Internet Explorer,否则请使用头 Content-Type: "text/html; charset=UTF-8";当不支持 Internet Explorer 时,请使用头 Content-Type: "application/xhtml+xml; charset=UTF-8"。

清单 1. 完整的 XHTML5 示例

<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> 
 <head> 
 <title>A micro blog, in XHTML5</title> 
 <style> 
<!-- Provide a fall-back for browsers that don't understand the new elements --> 
header, footer, nav, section, article, figure, aside { 
 display:block; 
} </style> 
 <script type="application/javascript"> 
  <!-- Hack support for the new elements in JavaScript under Internet Explorer --> 
  <!--[if IE]> 
   <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> 
  <![endif]--> 
 </script> 
 <script type="application/javascript"> 
  <!-- ... Other JavaScript goes here ... --> 
 </script> 
 </head> 
 <body> 
  <header>A micro blog</header> 
  <article> 
   <section> 
    <p> 
     There is something important I want to say: 
    </p> 
    <blockquote> 
     A stitch in time saves nine. 
    </blockquote> 
   </section> 
   <section><p>By the way, are you as excited about the World Cup as I am?</p> 
   </section> 
  </article> 
  <article> 
   <section> 
    <p> 
     Welcome to my new XHTML5 weblog <img src="/images/logo.png"/> 
    </p> 
   </section> 
  </article> 
  <aside> 
   <header>Archives</header> 
   <ul> 
    <li><a href="/2010/04">April 2010</a></li> 
    <li><a href="/2010/05">May 2010</a></li> 
    <li><a href="/2010/06">June 2010</a></li> 
   </ul> 
  </aside> 
  <footer>&#169; 2010 by Uche Ogbuji</footer> 
  <nav> 
   <ul> 
    <li><a href="/">Home</a></li> 
    <li><a href="/about">About</a></li> 
    <li><a href="/2010/06">Home</a></li> 
   </ul> 
  </nav> 
 </body> 
</html> 

  清单 1 使用 HTML5 DTDecl,并在顶部声明默认命名空间。本例中的 style 和 script 元素仅提供实际浏览器问题的解决方法。只有在使用其他 JavaScript 时才需要 script 元素。该文档使用了大量新 HTML5 元素,我不会详细介绍这些元素,因为它们不是 XML 特有的。注意,img 元素使用的是 “自闭合” 语法(换句话说,它以 /> 结束),版权符号使用的是数值实体形式 &#169;。

  可参阅 表 1 了解上述示例在不同浏览器中的行为概述。

表 1. 满足本文建议的 XHTML5 的浏览器支持

浏览器 行为
旧版浏览器(例如,Internet Explorer 6.x 或更早版本、 Netscape、Firefox 1.x) 呈现将是不可预测的。例如,“自闭合” 元素的结束标记可能是错误的。如果您使用 HTML 命名实体则不会出现任何错误。
Internet Explorer 7 或 8 由于使用的是 text/html MIME 类型,因此呈现将是常规的 “标记杂烩”,但是任何 DTDecl 都将触发 “标准模式”,比如 Internet Explorer 提供它。HTML 命名实体不会出现任何错误报告。
现代的、支持 HTML5 的浏览器,比如 Firefox 3.x、Safari 4 或最新的 Opera 或 Google Chrome 由于使用的是 MIME 类型,因此呈现将是 HTML5(而不是 XHTML5),但是会是在 “标准模式” 下。HTML 命名实体不会出现任何错误报告。
任何标准的 XML 1.x 处理器 将不会考虑 MIME 类型。解析器将会在 XHTML 命名空间看到所有元素。如果使用任何假的 HTML 命名实体,都会收到错误信息。


  结束语

  最近的一个重要情况是 W3C HTML 工作组发布了第一份公共工作草案 "Polyglot Markup: HTML-Compatible XHTML Documents",目的是提供有关 XHTML5 的更全面、准确和最新的消息。

  此外,对我来说,做出本文中的一些建议来说很痛苦。这些解决方法来自长期的痛苦体验,并且在将 XML 混合进现实 HTML 世界时,这是避免难以重现的 bug 和奇怪的不兼容性的惟一方法。这当然不是说我已经停止了提倡仔细的 XML 设计和最佳实践。最好将连接浏览器的最外面的组件保存为 XHTML5。所有类型的 XHTML 都能更好地呈现语言而不是携带信息的语言。您应该以其他 XML 格式传输大多数系统的主要信息。然后在最后将其转换为 XHTML5。您可能会好奇在最后时刻创建 XHTML5 的意义,但是请记住 Postel 法则,它建议严格执行生成的内容。通过为浏览器生成 XHTML5,其他人会很容易从您的网站和应用程序中提取信息。在这个混搭、web API 和数据项目时代,这是一个重要特性。

上一条:22个HTML5的初级技巧 下一条:开发人员需牢记的HTML5安全问题

相关文章

最新文章