什么是空元素?

时间:2010-02-17 09:24:07

标签: xml dom

根据XML规范,这是空元素的定义:

  

没有内容的元素被认为是空的。]空元素的表示是一个开始标记,紧跟一个结束标记,或一个空元素标记。

(见:http://www.w3.org/TR/REC-xml/#NT-content

现在,我对理解空元素标签没有问题:<i-am-empty/>并且不存在任何误解。但在我看来,标准在另一种情况下自相矛盾:一方面它表示任何没有content的标签都是空的,另一方面它表示这可以用一个开始标记来表示立即用一个结束标记。但是,如果我们看一下content的定义:

[43] content ::= CharData? ((element | Reference | CDSect | PI | Comment) CharData?)*

在我看来,content由两个可选部分CharData?和一个()*组成。但由于这两个部分都是可选的,因此它意味着没有任何东西(如没有字符)与此产品相匹配。所以,如果我试图将这个内容定义与<am-i-empty-or-not></am-i-empty-or-not>内的任何内容相匹配,我会得到一个积极的匹配。所以,一方面这是一个空标签,因为它是“一个开始标签后紧跟一个结束标签”,另一方面它不是空的,因为在标签之间我可以正确地匹配生产规则的定义[对于内容,在这种情况下,它包含内容,这意味着它不能为空。

有人可以解释哪些规则优先吗?有没有人知道任何对此有不同意见的DOM或解析器实现?

3 个答案:

答案 0 :(得分:11)

  

但由于这两个部分都是可选的,因此没有任何内容(如没有字符)与此产品相匹配。

这可能是真的,但关于这个问题的规范中的措辞非常明确。在下一段中甚至有空元素的例子。

<IMG align="left"
 src="http://www.w3.org/Icons/WWW/w3c_home" />
<br></br>
<br/>

所以唯一的方法(在这种情况下,用周围的措辞和例子)来阅读

  

没有内容的元素

将包括“(在匹配制作时)完全为空的内容”(即零长度,甚至不是空格)。

答案 1 :(得分:8)

我想查看“empty”的不同变体实际上是空的。

变体A

<Santa/>

给出了

|- NODE_DOCUMENT #document ""
   |- NODE_ELEMENT Santa ""

变体B

<Santa></Santa>

给出一个DOM树:

|- NODE_DOCUMENT #document ""
   |- NODE_ELEMENT Santa ""

变体C

<Santa> 空间 </Santa>

给出一个DOM树:

|- NODE_DOCUMENT #document ""
   |- NODE_ELEMENT Santa ""

变化D

<Santa> 标签 </Santa>

给出一个DOM树:

|- NODE_DOCUMENT #document ""
   |- NODE_ELEMENT Santa ""

变异E

<Santa> CRLF
</Santa>

给出一个DOM树:

|- NODE_DOCUMENT #document ""
   |- NODE_ELEMENT Santa ""

文本的所有变体都提供相同的DOM树。当要求XML文档自行序列化时,DOM树:

|- NODE_DOCUMENT #document ""
   |- NODE_ELEMENT Santa ""

产生序列化文本:

<?xml version="1.0"?>
<Santa/>

手动添加空文本节点

我想看看如果我构建DOM树会发生什么:

|- NODE_DOCUMENT #document ""
   |- NODE_ELEMENT Santa ""
      |- NODE_TEXT #text ""

使用伪代码:

XmlDocument doc = new XmlDocument();
XmlElement santa = doc.appendChild(doc.CreateElement("Santa"));
santa.appendChild(doc.CreateText(""));

当该DOM文档保存到流中时,它将显示为:

<?xml version="1.0"?>
<Santa/>

即使强制元素有一个子元素(即强制不为空),DOM也会将其视为空。

使用空格强制文本节点

然后如果我确保在TEXT节点中放置一些空格:

XmlDocument doc = new XmlDocument();
XmlElement santa = doc.appendChild(doc.CreateElement("Santa"));
santa.appendChild(doc.CreateText(" "));

它以XML格式出现:

<?xml version="1.0" ?>
<Santa> </Santa>

使用DOM树:

|- NODE_DOCUMENT #document ""
   |- NODE_ELEMENT Santa ""
      |- NODE_TEXT #text " "

有趣;它不是圆形的。

强制使用TAB CRLF

XmlDocument doc = new XmlDocument();
XmlElement santa = doc.appendChild(doc.CreateElement("Santa"));
santa.appendChild(doc.CreateText(TAB+LF+CR));

它以XML格式出现:

<?xml version="1.0"?>
<Santa>TABLF
CR    
</Santa>

使用DOM树:

|- NODE_DOCUMENT #document ""
   |- NODE_ELEMENT Santa ""
      |- NODE_TEXT #text "\t\n\n"

是的,XML将所有 CR 转换为 LF ,是的,它不是圆形的。如果您解析:

<?xml version="1.0"?>
<Santa>TABLF
CR   
</Santa>

您将获得以下DOM树:

|- NODE_DOCUMENT #document ""
   |- NODE_ELEMENT Santa ""

设置element.text

最后,我们来看看如果通过它的.text属性设置元素的文本会发生什么。

设置无文字

XmlDocument doc = new XmlDocument();
XmlElement santa = doc.appendChild(doc.CreateElement("Santa"));
//santa.text = ""; example where we don't set the text

给出了DOM树:

|- NODE_DOCUMENT #document ""
   |- NODE_ELEMENT Santa ""

和XML:

<?xml version="1.0"?>
<Santa/>

设置空文

XmlDocument doc = new XmlDocument();
XmlElement santa = doc.appendChild(doc.CreateElement("Santa"));
santa.text = ""; //example where we do set the text

给出了DOM树:

|- NODE_DOCUMENT #document ""
   |- NODE_ELEMENT Santa ""
      |- NODE_TEXT #text ""

和XML:

<?xml version="1.0"?>
<Santa/>

设置单个空间

XmlDocument doc = new XmlDocument();
XmlElement santa = doc.appendChild(doc.CreateElement("Santa"));
santa.text = " ";

给出了DOM树:

|- NODE_DOCUMENT #document ""
   |- NODE_ELEMENT Santa ""
      |- NODE_TEXT #text " "

和XML:

<?xml version="1.0"?>
<Santa> </Santa>

设置更多whitepsace

XmlDocument doc = new XmlDocument();
XmlElement santa = doc.appendChild(doc.CreateElement("Santa"));
santa.text = LF+TAB+CR;

给出了DOM树:

|- NODE_DOCUMENT #document ""
   |- NODE_ELEMENT Santa ""
      |- NODE_TEXT #text "\n\t\n"

和XML:

<?xml version="1.0"?>  
<Santa>LF
TABLF
</Santa>

从某种角度来看,他们告诉你的是真实的。

  • 解析时,元素中只包含空格的xml字符串将为空
  • 在其文本节点中仅包含空格的DOM元素将在转换为xml字符串时呈现空白

答案 2 :(得分:7)

<element />

<element></element>

都是空元素。必须将标准中的任何产品解释为具有此结果。