Новости | 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/>]