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