parser

Написать ответ на текущее сообщение

 

 
   команды управления поиском

хардкорное тестирование Dom в 3.2.1

Vitaliy 05.03.2006 02:55

Не знаю можно ли назвать, это Hardcore, выкладываю класс который годик с лишним работал на паре сайтов под parser314 windows / freebsd
, он и сейчас работает на 316 под windows, а на 321 пишет в лог следующее
callsections.p(145:95): 'getAttribute' method can only be called on nodes of ELEMENT type [parser.runtime]

Вопрос: как учитывать разницу между веткой 316 и 321 при работе с Dom ?
@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/>]