|
Парсинг XML в AOLserver
Автор: © Irving Washington
| ||||||||||||||||||||||||||||||||
|
AOLserverAOLserver это open-source, многопоточный (multi-threaded), высокопроизводительный веб сервер. Хотя AOLserver менее известен, чем Apache, по некоторым характеристикам он его превосходит: богатое и хорошо продуманное расширение API, превосходный API для стыковки с базами данных, хорошо интегрированный интерпретатор Tcl. Чтобы узнать больше об AOLServer'е прочитайте мою предыдущую статью.XMLЕсли вы собираетесь серьезно работать с языком XML, вам нужно изучить его, но где-нибудь в другом месте - явно не в этой статье. Самое лучшее резюме об XML, которое я видел: XML это (неэффективный) способ представления данных в древовидной форме в виде текстовых (ASCII) файлов. Представление данных в виде текста как раз подходит для таких целей, потому что текстовой формат прост. Древовидная структура подходит, потому что много всего можно представить в виде деревьев (например, незамкнутый список - это просто вырожденное дерево, а замкнутый список может быть описан с помощью некоторого множества деревьев). Неэффективность - это, конечно, нехорошо, но ей обычно жертвуют в пользу расширяемости и повсеместной применимости, которую имеет XML (много инструментов, много информации).Поддержка XML в AOLserverОбработка XML (парсинг и модификация XML-документов) в AOLserver возможна благодаря модулю ns_xml, который написан ArsDigita. Этот модуль - оболочка (wrapper) над версиями 2.x (>2.2.5) библиотеки libxml, она добавляет командуns_xml во встроенный интерпретатор Tcl.
Вы можете
загрузить исходные тексты или получить этот модуль прямо из CVS repository так:
cvs -d:pserver:anonymous@cvs.aolserver.sourceforge.net:/cvsroot/aolserver login cvs -z3 -d:pserver:anonymous@cvs.aolserver.sourceforge.net:/cvsroot/aolserver co nsxmlНажмите Enter после ввода первой команды, так как CVS ждет ввода пароля (который в нашем случае пуст).
С декабря 2000-го года дистрибутивы Linux обычно поставляются с
версией 1.x библиотеки libxml, так что есть вероятность, что
вам самим придется установить версию 2.x (в будущем все изменится,
так как все переходят на версии 2.x). Чтобы установить модуль
ns_section "ns/server/${servername}/modules"
ns_param nsxml ${bindir}/ns_xml.so
и перезапустите AOLserver. Чтобы проверить, что модуль загружается,
посмотрите файл server.log, обычно я использую shell с такой командой:
tail -f $AOLSERVERDIR/log/server.logЭто так же хороший способ отладки скриптов Tcl, так как AOLserver будет сбрасывать детальную информацию об ошибках туда же, каждый раз, когда возникает ошибка в скрипте. Краткая справка по XMLВот небольшая справка по всем командам, доступным через ns_xml.
Простой примерПростой и поучительный пример - разбор древовидной структуры документа с последующей ее печатью. Что делает этот процесс:
-persist для
ns_xml parse
, вам придется явно вызывать ns_xml doc
free $doc_id чтобы освободить, память выделенную под данный документ,
в противном случае она освободится автоматически после выполнения скрипта.
Код мог бы выглядеть вот так:
proc dump_node {node_id level} {
set name [ns_xml node name $node_id]
set type [ns_xml node type $node_id]
set content [ns_xml node getcontent $node_id]
ns_write "<li>"
ns_write "node id=$node_id name=$name type=$type"
if { [string compare $type "attribute"] != 0 } {
ns_write " content=$content\n"
}
}
proc dump_tree_rec {children} {
ns_write "<ul>\n"
foreach child_id $children {
dump_node $child_id
set new_children [ns_xml node children $child_id]
if { [llength $new_children] > 0 } {
dump_tree_rec $new_children
}
}
}
proc dump_tree {node_id} {
dump_tree_rec [list $node_id] 0
}
proc dump_doc {doc_id} {
ns_write "doc id=$doc_id<br>\n"
set root_id [ns_xml doc root $doc_id]
dump_tree $root_id
}
set xml_doc "<test version="1.0">this is a
<blind>test</blind> of xml</test>"
set doc_id [ns_xml parse $xml_doc]
dump_doc $doc_id
Команда ns_xml parse выдаст ошибку,
если документ XML неправильный (например, плохо сформирован), поэтому в
ходе выполнения программы мы можем выловить ошибку и выдать сообщение.
Например:
if { [catch {set doc_id [ns_xml parse $xml_doc]} err] } {
ns_write "There was an error parsing the following XML document: "
ns_write [ns_quotehtml $xml_doc]
ns_write "Error message is:"
ns_write [ns_quotehtml $err]
ns_write " |