| Новости | FAQ | Авторы | Документация | В действии | Библиотека |
| Инструменты | Полезные ссылки | Хостинги | Скачать | Примеры | Форум |
Vitaliy 05.03.2006 02:55
Не знаю можно ли назвать, это Hardcore, выкладываю класс который годик с лишним работал на паре сайтов под parser314 windows / freebsd@CLASS
callsections
##################################################################################
## ##
## автор Юлия Сергеева ##
## http://viju.tvercity.net/articles/ ##
## juliachina@mail.ru ##
## лицензия: пользуйтесь на здоровье ##
## улучшите сообщите ##
## ##
## ##
## @process_sec[name]: ##
## начиная с секции с <sectiion name="$name"> ##
## 1. проходим по всем вызовам call-section внутри этой секции ##
## 2. при каждом найденном вызове: ##
## - выясняем есть ли секция с таким же именем ##
## - если есть: для нее повторяем тоже самое начиная с п.1 ##
## и в результате получаем данные для вставки (xdoc) ##
## - если нет: данные для вставки: [] ##
## - заменяем место вызова полученными данными ##
## 3. накладываем xslt на данную секцию - получаем xdoc ##
## ##
## !!! все преобразования xslt накладываются на всю загруженную xml-ку ##
## а не на отдельные секции: ##
## => в xslt должна быть ##
## 1. явно указана обрабатываемая секция ##
## <xsl:template match="section[@name='....']" ##
## 2. должен присутствовать <xsl:template match="text()"/> ##
## ##
## ##
## ##
## # Test CallSections_beta ##
## # test 1 ##
## <div style="background-color: blue;color:white;"> ##
## CallSections_beta: test 1</div> ##
## $cs[^callsections_beta::create[/test/.pages/about.ai.xml]] ##
## ##
## $res[^cs.process_sec[meta]] ##
## #^res.string[$.method[html]] ##
## $cs.test ##
## ##
## # test 2 ##
## <div style="background-color: blue;color:white;"> ##
## CallSections_beta: test 2</div> ##
## ^cs.includeXmls[] ##
## #^taint[^cs.basexml.string[]] ##
## <br/> ##
## $cs.test ##
##################################################################################
@create[hash]
$basexml[^xdoc::load[$hash.pagePath]]
$test[create:: загружена базовая xml $hash.pagePath <br/>]
^if(def $hash.params){$params[$hash.params]}{$params[]}
^includeXmls[]
###############################################################################
@process_sec[name][i;strpath;callsections_nodes;secpath;sec_node;data;node]
$test[$test process_sec:: process section name $name ... <br/>]
$strpath[/page/section[@name='$name']//call-section]
$callsections_nodes[^basexml.select[$strpath]]
^for[i](0;$callsections_nodes-1){
$node[$callsections_nodes.$i]
$sec_name[^node.getAttribute[name]]
# find secion with name $sec_name
$secpath[/page/section[@name='$sec_name']]
$sec_node[^basexml.selectSingle[$secpath]]
$test[${test} process_sec:: ${sec_name}<br/>]
# if finded - process_sec[sec_name]
^if($sec_node is xnode){
$data[^process_sec[$sec_name]]
}{
$data[]
}
# replace
^inclusion[$data;$node]
}
# возвращаем xdoc или строка или xnode
$result[^transform_sec[$name]]
###############################################################################
@transform_sec[name][path;sec_node;xslpath;transformedDoc]
$path[/page/section[@name='$name']]
$sec_node[^basexml.selectSingle[$path]]
^if($sec_node is xnode){
$xslpath[^sec_node.getAttribute[xslt]]
# transform
^if(-f $xslpath){
$transformedDoc[^basexml.transform[$xslpath][$params]]
$test[${test} transform_sec:: результат трансформации $name :<br/> ^transformedDoc.string[$.method[html]]<br/>]
$result[$transformedDoc]
}{
$test[${test} transform_sec:: не нашел xslt для секции $name<br/>]
$result[$sec_node]
}
}{
$test[${test} transform_sec:: не нашел секцию $name<br/>]
$result[none]
}
###############################################################################
@incAsDocfrag[data;insetnode;replace][root;buffer;docfrag;tmp1;tmp2;parelem]
# вставка типа DocumentFragment
# $insetnode /xnode/ место вставки в базовой xml ($basexml)
# (элемент, который заменяется данным фрагментом)
# если replace="false" - вставляем фрагмент как дочерний для insetnode, а не замещаем
# $data /xdoc/ исходный документ (который целиком копируется вместо $insetnode)
# $data /xnode/
# копируем 'в буфер' нужный кусок дерева из исходного документа $xresdoc
^if($data is xdoc){$root[$data.documentElement]}
^if($data is xnode){$root[$data]}
$buffer[^basexml.importNode[$root](1)]
# создаем в целевом документе $basexml фрагмент и помещаем туда данные из буфера
$docfrag[^basexml.createDocumentFragment[]]
$tmp1[^docfrag.appendChild[$buffer]]
# замещаем элемент 'место вставки' на наш фрагмент или просто дабавляем
^if((def $replace) && ($replace eq "false")){
$tmp2[^insetnode.appendChild[$docfrag]]
$test[${test} incAsDocfrag:: добавили фрагмент<br/>]
}{
$parelem[$insetnode.parentNode]
$tmp2[^parelem.replaceChild[$docfrag;$insetnode]]
$test[${test} incAsDocfrag:: заменили фрагмент $tmp2.nodeName c xml = ^tmp2.getAttribute[xml] c xslt = ^tmp2.getAttribute[xslt]<br/>] #!!!!!
}
# xdoc не возвращает ?
#$return[$tmp2]
###############################################################################
@incAsCdata[data;insetnode][newCdataNode;cdata;parelem;tmp;name]
# вставка типа CDATA (замена на CDATA)
# $insetnode /xnode/ место вставки в базовой xml ($basexml)
# $data /xdoc/ исходный документ (который целиком копируется вместо $insetnode)
# $data /xnode/ содержимое узла (д.быть в cdata)
^if($data is xdoc){
$cdata[^data.string[
$.omit-xml-declaration[yes]
$.indent[no]
]
]
}
^if($data is xnode){
^if($data.firstChild.nodeType == 4){
$cdata[$data.firstChild.nodeValue]
}{
$cdata[эта section должна содержать CDATA]
}
}
^if($data is string){
$cdata[$data]
}
$newCdataNode[^basexml.createCDATASection[$cdata]]
# test
$name[^insetnode.getAttribute[name]]
$test[${test} incAsCdata:: cdata для call-section ${name} : $cdata <br/>]
# замещаем элемент 'место вставки' на наш фрагмент
$parelem[$insetnode.parentNode]
$tmp[^parelem.replaceChild[$newCdataNode;$insetnode]]
$return[$newCdataNode]
###############################################################################
@inclusion[data;insetnode][type]
# $insetnode /xnode/ место вставки в базовой xml ($basexml), call-section элемент
# $data /xdoc/ исходный документ (который целиком копируется вместо $insetnode)
# $data /string/
^if($data is xdoc || $data is xnode || $data is string){
$test[${test} inclusion:: is xdoc<br/>]
# замена элемента call-section на данные
# $data -> $basexml
^if($insetnode is xnode){
$test[${test} inclusion:: insert xdoc<br/>]
# вставка
$type[^insetnode.getAttribute[as]]
^if($type eq "cdata"){
$return[^incAsCdata[$data;$insetnode]]
}{
$return[^incAsDocfrag[$data;$insetnode]]
}
}
}{
#если $data например строка - удаляем элемент call-section
$test[${test} inclusion:: insert nothing<br/>]
$parelem[$insetnode.parentNode]
$return[^parelem.removeChild[$insetnode]]
}
###############################################################################
@includeXmls[][i;strpath;section_nodes;sec_node;xdoc_from_file;path;newsection;oldxslt;data;newCdataNode;tmp]
# вставка всех секций из xml файлов,
# если есть для секции аттрибут xml
# и обработка всех секций типа parser
$strpath[/page/section]
$section_nodes[^basexml.select[$strpath]]
^for[i](0;$section_nodes-1){
$sec_node[$section_nodes.$i]
# вставка внешнего xml
$path[^sec_node.getAttribute[xml]]
$oldxslt[^sec_node.getAttribute[xslt]]
$test[${test} includeXmls:: работаем с секцией name = ^sec_node.getAttribute[name] <br/>]
^if(-f $path){
^try{
$xdoc_from_file[^xdoc::load[$path]]
$test[${test} includeXmls:: загрузил данные в xdoc из $path <br/>]
^if($oldxslt ne ""){
$newsection[^xdoc_from_file.selectSingle[section]]
^newsection.setAttribute[xslt;$oldxslt]
$test[${test} includeXmls:: оставили ссылку на xslt, которая была $oldxslt <br/>]
}{
$test[${test} includeXmls:: ссылка на xslt будет заменена xslt из включаемого файла<br/>]
}
$node_ai[^incAsDocfrag[$xdoc_from_file;$sec_node]]
}{
^if($exception.type eq xml){
$exception.handled(1)
$test[$test includeXmls:: не смог загрузить его в xdoc<br/>Ошибочный XML3,<pre>$exception.comment</pre>]
}
}
}
# обрабатываем внешний parser
$ppath[^sec_node.getAttribute[pref]]
^if(-f $ppath){
$file[^file::load[text;$ppath]]
$data[^process[$caller.self]{^taint[as-is][$file.text]}[
$.file[$ppath]
]]
$newCdataNode[^basexml.createCDATASection[$data]]
$tmp[^sec_node.appendChild[$newCdataNode]]
}
}
$test[${test} includeXmls:: результат: <br/> ^taint[^basexml.string[]]<br/>]