首页 > 解决方案 > 在具有 XML 语法的 HTML 中,可以使用具有除 HTML、SVG 和 MathML 之外的命名空间的元素吗?

问题描述

长期以来,我一直认为用于编写 HTML 文档的 XML 语法的一个优点是它还允许在 HTML 文档中包含具有不是 HTML 标准指定的名称空间的元素。例如,描述书籍的用户创建命名空间中的用户创建元素。但是,阅读 WhatWG 规范,这似乎是被禁止的,或者我不知道该怎么做(我的意思是,以符合规范的方式)。

我正在考虑类似于以下文档的内容。

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    …
  </head>
  <body>
    <h1>Title</h1>
    <book xmlns="http://example.com/my-book-namespace">
      …
    </book>
  </body>
</html>

我意识到浏览器当然不知道如何渲染来自未知名称空间的这些元素,但这可能不是问题(我希望浏览器会简单地忽略这些元素)。例如,页面上的一些 javascript 可以使用这些元素作为数据,以便动态生成 HTML 元素。

例如,本关于 Java Server Faces 的教程包含了 JSF 名称空间中的元素,看起来像是一个符合标准的 XHTML 页面。

但是规范似乎暗示这样的例子是不符合标准的,甚至可能没有办法在 HTML 文档中包含这样的元素。“每个单独元素的确切允许内容取决于该元素的内容模型,如本规范前面所述。元素不得包含其内容模型不允许的内容。” (元素);并且该body元素仅将流内容指定为内容模型;这似乎不允许使用 HTML 规范明确指定的元素之外的元素。

那么,如果我坚持只生成符合规范的 HTML 文档,我是否应该避免在 HTML 文档中包含来自不同于 HTML、SVG 和 MathML 命名空间的命名空间的元素?

标签: htmlxmlsyntaxxhtmlspecifications

解决方案


虽然 WHATWG 的 HTML 规范确实指出

元素不得包含其内容模型不允许的内容。

正如您所引用的,第 13.2.6.4.7 章(“in body”插入模式)说明了 HTML 解析器应该对您的示例文档执行的实际操作:

任何其他开始标记:
为标记插入 HTML 元素

https://html.spec.whatwg.org/#parsing-main-inbody)。

尽管第 13 章中给出的解析规则将错误恢复和 SGML 风格的标签推理操作(后者仅适用于 HTML 序列化)混合在一起,但在没有其他规则的情况下,它们也应该适用于 XML 内容(或任何语法规则完全可以应用于 XML)。

因此,浏览器不会忽略您的book元素,而是会根据13.2.6.1 创建和插入节点 - 插入外部元素来处理它。如果您的文档有实际book内容,例如以下示例,

<?xml version="1.0"?>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
   <title>Test</title>
  </head>
  <body>
    <h1>Title</h1>
    <book xmlns="http://example.com/my-book-namespace">
      <descr xmlns="http://example.com/my-book-namespace">
        some text
      </descr>
    </book>
  </body>
</html>

浏览器会将descr文本内容呈现为无样式内容,但您可以使用 CSS@namespace规则对其进行样式设置,如下所示:

<?xml version="1.0"?>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
   <title>Test</title>
   <style>
     @namespace url(http://example.com/my-book-namespace);
     descr { color: blue }
   </style>
  </head>
  <body>
    <h1>Title</h1>
    <book xmlns="http://example.com/my-book-namespace">
      <descr xmlns="http://example.com/my-book-namespace">
        some text
      </descr>
    </book>
  </body>
</html>

推荐阅读