Что такое пустой элемент? - PullRequest
20 голосов
/ 17 февраля 2010

Согласно спецификации 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> Я бы получил положительный матч.Итак, с одной стороны, это пустой тег, потому что это «начальный тег, за которым сразу следует конечный тег», с другой стороны, он не пустой, потому что между тегами я могу положительно соответствовать определению правила производства [43] для контента, в этом случае он содержит контент, что означает, что он не может быть пустым.

Кто-нибудь может объяснить, какие правила имеют приоритет?Кто-нибудь знает о каких-либо реализациях DOM или парсера, которые имеют различные мнения по этому поводу?

Ответы [ 3 ]

11 голосов
/ 17 февраля 2010

Но поскольку обе эти части являются необязательными, это будет означать, что ничто (например, отсутствие символов) не соответствует этой постановке.

Это может быть правдой, но формулировка в спецификации по этому вопросу довольно ясна. В следующем абзаце есть даже примеры для пустых элементов.

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

Таким образом, единственный способ (в данном контексте, с окружающей формулировкой и примерами) прочитать

Элемент без содержимого

будет включать «содержимое, которое (при сопоставлении с продукцией) является полностью пустым» (т.е. нулевой длины, даже не пробела).

8 голосов
/ 11 декабря 2015

Я хотел проверить, какие разные варианты "empty" на самом деле пусты.

Вариация A

<Santa/>

дает дерево

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

Вариация B

<Santa></Santa>

дает дерево DOM:

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

Вариация C

<Santa> Space </Santa>

дает дерево DOM:

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

Вариация D

<Santa> Tab </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 " "

Интересный; это не круто.

Force 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><kbd>TAB</kbd><kbd>LF</kbd>
<kbd>CR</kbd>    
</Santa>

с деревом DOM:

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

Да, XML преобразует все CR в LF , и да, он не может быть использован для округления. Если вы анализируете:

<?xml version="1.0"?>
<Santa><kbd>TAB</kbd><kbd>LF</kbd>
<kbd>CR</kbd>   
</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>

Настройка больше белого пространства

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><kbd>LF</kbd>
<kbd>TAB</kbd><kbd>LF</kbd>
</Santa>

Итак, то, что они сказали вам, было правдой с определенной точки зрения.

  • строка xml, содержащая только пробелы в элементе, будет пустой при анализе
  • элемент DOM, который содержит только пробел в своем текстовом узле, будет отображать пробел при преобразовании в строку XML
7 голосов
/ 17 февраля 2010
<element />

и

<element></element>

оба являются пустыми элементами. Любые произведения из стандартов должны быть интерпретированы, чтобы иметь этот результат.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...