Spiga

为什么 script 标签不能写成自关闭形式

2011-07-08 13:50 by Cat Chen, 3053 visits, 收藏, 编辑

今天早上在 Stack Overflow 看到了这个问题: Why don't self-closing script tags work? 。答案给出的解释是,在 XHTML 的标准里面规定非 EMPTY 标签不能使用自关闭形式。注意这里使用的是全大写的 EMPTY ,所以我不把它翻译为「空白」。

那么 EMPTY 到底是什么呢?写过 DTD 的人应该知道它是个关键字,用来指明一个标签的内容必须是空白,而不能包含文本内容或子节点。看看具体的例子就很容易明白了:

<!ELEMENT img EMPTY>
<!ATTLIST img   %attrs;
  src %URI; #REQUIRED
  alt %Text; #REQUIRED
  longdesc %URI; #IMPLIED
  height %Length; #IMPLIED
  width %Length; #IMPLIED
  usemap %URI; #IMPLIED
  ismap (ismap) #IMPLIED
  >

这是 img 标签的定义。 ELEMENT 关键字说明它是一个元素, EMPTY 关键字说明它的内容必须是空白。因此,我们可以使用自关闭形式:

<img src="image.png" alt="some image" />

留意 ATTLIST 里面声明了两个属性是 #REQUIRED 的,所以必须提供。

接下来我们再看看 script 标签的定义:

<!ELEMENT script (#PCDATA)>
<!ATTLIST script
  id ID #IMPLIED
  charset %Charset; #IMPLIED
  type %ContentType; #REQUIRED
  language CDATA #IMPLIED
  src %URI; #IMPLIED
  defer (defer) #IMPLIED
  xml:space (preserve) #FIXED 'preserve'
  >

可以看到 script 标签通过 (#PCDATA) 声明了它的内部允许包含 CDATA 数据,因此它不是一个带 EMPTY 关键字的标签,也就不可能使用自关闭的写法。

总结一下:有空看看 Stack Overflow 还是挺有意思的。学习 DTD 的语法,并且看看 XHTML 1.0 Strict DTD 也会帮助你增加对 XHTML 的理解。

Add your comment

10 条回复

  1. #1楼 Gray Zhang      2011-07-08 13:55
    答案就是,XHTML不是XML,这本身就是一个夹在HTML和XML之间的四不像
     回复 引用 查看   
  2. #2楼 Ivony...      2011-07-08 14:04
    XHTML是与XML和HTML都兼容的一种文档格式。对于XML解释器而言:
    <script></script>和<script />是一样的,对于HTML解释器而言:<img>和<img />是一样的。XHTML就是一种,对于XML和HTML解释器都有大致相同的行为的一种文档格式。
     回复 引用 查看   
  3. #3楼 Jeffrey Zhao      2011-07-08 17:08
    @Gray Zhang
    XHTML就是XML+规范。
     回复 引用 查看   
  4. #4楼 riccc      2011-07-08 17:10
    早期的IE7中script标签写成自闭形式,会导致后面的html全部无法解析
     回复 引用 查看   
  5. #5楼 xiao_p      2011-07-08 23:37
    这篇文章的回复都是牛人哈,留个足迹

    DTD为啥不xml schema? 难道因为DTD方便快捷?
     回复 引用 查看   
  6. #6楼 苏飞      2011-07-09 18:21
    XHTML就是XML+标准
     回复 引用 查看   
  7. #7楼[楼主] Cat Chen      2011-07-09 18:33
    @xiao_p
    DTD 和 Schema 的描述能力有交集,但各自又有对方所没有的特性,所以选择 DTD 可能是从特性的角度出发吧。

    Schema 有一个很不方便的地方在于,它定义一个元素的子元素规则就那么几种形式,要么是顺序型,要么是多选一型,这使得子元素的使用很不灵活。你要制订 a 标签内可以出现 <a><x /><y /></a> 又能出现 <a><y /><x /></a> , Schema 就做不到了,这时候只能选择 DTD 。
     回复 引用 查看   
  8. #8楼 Ivony...      2011-07-09 23:42
    引用Cat Chen:
    @xiao_p
    DTD 和 Schema 的描述能力有交集,但各自又有对方所没有的特性,所以选择 DTD 可能是从特性的角度出发吧。

    Schema 有一个很不方便的地方在于,它定义一个元素的子元素规则就那么几种形式,要么是顺序型,要么是多选一型,这使得子元素的使用很不灵活。你要制订 a 标签内可以出现 <a><x /><y /></a> 又能出现 <a><y /><x /></a> , Schema 就做不到了,这时候只能选择 DTD 。



    这个Schema当然是能做到的。。。。
    其实就是一个sequence里面嵌一个choice就行了。
     回复 引用 查看   
  9. #9楼 skyaspnet      2011-07-10 16:52
    学习。。。
     回复 引用 查看   
  10. #10楼[楼主] Cat Chen      2011-07-11 09:06
    @Ivony...
    好吧,我之前一直不知道可以这样做。
     回复 引用 查看