Подтвердить что ты не робот

Что такое пустой элемент?

В соответствии с спецификацией 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? и группы ()*. Но поскольку обе эти части являются необязательными, это будет означать, что ничто (как и отсутствие символов) не соответствует этой продукции. SO, если я попытаюсь сопоставить это определение содержимого с тем, что находится внутри <am-i-empty-or-not></am-i-empty-or-not>, я бы получил положительное совпадение. Итак, с одной стороны, это пустой тег, потому что это "начальный тег, за которым сразу следует конечный тег", с другой стороны, он не пуст, потому что между тегами я могу положительно сопоставлять определение производственного правила [ 43] для содержимого, и в этом случае он содержит контент, что означает, что он не может быть пустым.

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

4b9b3361

Ответ 1

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

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

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

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

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

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

Ответ 2

<element />

и

<element></element>

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

Ответ 3

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

Вариация 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/>

Вручное добавление пустого текста node

Я хотел посмотреть, что произойдет, если я построю дерево 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 делает его пустым.

Текст команды node с пробелом

И тогда, если я обязательно поставлю некоторые пробелы в TEXT node:

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, и да, это не round-trippable. Если вы разбираете:

<?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>

Настройка большего количества белого цвета

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, содержащий только пробел в тексте node, отобразит пробел при преобразовании в строку xml