xmlhack.ru XML-форумы
Обсуждение XML и связанных с ним технологий

DOM XML: конфликт префикса и пространства имён


Автор Сообщение
detail
Новичок

Зарегистрирован: 07.05.2003
Сообщения: 4
Откуда: Novosibirsk
Посетить сайт автора
[4395] Ср Май 07, 2003 09:27
DOM XML: конфликт префикса и пространства имён
Странный глюк нашёл при работе с модулем DOM XML в PHP.

Вытаскиваю из базы данных строки и для каждой из них создаю узел и добавляю как детей к нужному элементу в документе.

<?
while($row = $result->fetchRow())
{
$option = $form->_dom->create_element("txf:option");
$option_in_form = $form->_input["cparent"]->append_child($option);
$option_in_form->set_attribute("value", $row[0]);
$option_in_form->append_child ($form->_dom->create_text_node (iconv ("windows-1251", "UTF-8", $row[1])));
}

$a = xpath_eval($form->_xpath, "//txf:option");
print(sizeof($a->nodeset));
?>

До этого в документе не было элементов txf:option, а вот этот запрос XPath выдаёт... пустой результат! Если перед этим преобразовать объект документа в строку, а затем вновь в объект, тогда запрос выдаст все вставленные элементы. При этом, аналогично запросу XPath, без перезагрузки документа глючит преобразование XSLT (используется libxslt).

Умный человек просвятил:

Цитата:

Я тоже, когда на это впервые напоролся - очень долго не мог понять в чем проблема. Как оказалось - в невнимательном чтении спецификаций :)

Суть в том, что PHP 4.2.x не поддерживает создание XML элементов с XML namespace, а 4.3.x хотя и поддерживает (или я ошибаюсь? сам-то все еще на 4.2.3 сижу), однако в твоем примере это не используется (если мне не изменяет память - нужно использовать create_element_ns()). Так вот, исходя из сказанного выше твой пример создает правильный XML документ, визуально идентичный тому, что тебе нужен, однако не являющийся таковым с точки зрения XML библиотеки. Дело в неоднозначности трактовки символа ':' в имени XML элемента. По спецификации XML - он может использоваться в именах XML элементов, а по спецификации XML Namespaces - он же используется для разделения префикса namespace и непосредственно имени XML элемента. Почему авторы спецификации допустили такую лажу - не знаю, однако это так. В результате твой пример создает не элемент с именем option в XML namespace txf, а элемент с именем txf:option в дефолтовом XML namespace. Когда же ты парсишь свой документ вновь - этот же самый элемент воспринимается уже как элемент с именем option в XML namespace txf, поскольку в документе присутствует декларация соответствующего XML namespace. Вот такая фигня :)



Далее предлагался код, который решал эту проблему, но я сделал свой, в котором создавал элемент option и затем задавал ему пространство имён. Но вопрос более фундаментальный: что это - конфликт спецификаций или мелкое недоразумение в их применении в php?
olpa
Любитель

Зарегистрирован: 23.04.2002
Сообщения: 981
Откуда: Санкт-Петербург
Посетить сайт автора
[4397] Ср Май 07, 2003 11:03

По-моему, умный человек совершенно прав. Проблема возникла из-за нестыковки спецификаций. Пространства имён появились уже после XML и являются надстройкой над XML.

Цитата:

В результате твой пример создает не элемент с именем option в XML namespace txf, а элемент с именем txf:option в дефолтовом XML namespace.



В точном соответствии со спецификацией DOM.

Так должно быть всюду, не только в PHP.