1# Set default value for process variable 2 set pos 0 ;# Position search Cursor 3 set buffer {} ;# Buffer for text 4 set action {findXMLstart} ;# Current operation 5 set find_start 0 ;# Index for start action 6 set find_end 0 ;# Index for end action 7 set total_length [string length $source_xml] ;# Total length XML document 8 set nodes_list {} ;# List of inserted nodes 9 set count_nodes 0 10 set count_text 0 11# Type action: 12# getText 13# findXMLstart 14# findXMLend 15# findCDATAend 16 17set xml [eval {create -file $a_args(-file)} $attribute ] 18# Process parse ====================================== 19 while {$pos < $total_length } { 20 set char [string index $source_xml $pos] 21 switch -- $action { 22 findXMLstart { 23 set pos [string first "<" $source_xml $pos] 24 if { $pos == -1 } { set pos $total_length ; continue } 25 incr pos 26 set action findXMLend 27 } ;# switch --- findXMLstart 28 29 findCDATAend { 30 } 31 32 findXMLend { 33 set new_pos [string first ">" $source_xml $pos] 34 if { $new_pos == -1 } { set pos $total_length ; continue } 35 36 set node_info [string range $source_xml [expr $pos] [expr $new_pos - 1]] 37 gui::msgDebug "__PARSE: @$node_info@ || [string index $source_xml $pos] || [string index $node_info end]" 38 switch -- [string index $source_xml $pos] { 39 ? { 40 foreach { node_name node_attr } [simxml::parseNode $node_info] { break } 41 set node_name [string toupper $node_name] 42 lappend xmlPrCommand($xml:$node_name) $node_attr 43 gui::msgDebug "COMMAND: $node_name || $node_attr" 44 set pos [expr $new_pos] 45 set action findXMLstart 46 continue 47 } 48 ! { 49 set tag_name {} 50 regexp {.([^\s]+)} $node_info -> tag_name 51 set tag_name [string toupper $tag_name] 52 switch -- $tag_name { 53 ENTITY { 54 if [regexp {\w+\s+(\w+)\s+(["'])(.*?)\2>?} $node_info -> en_name {} en_value] { 55 entity $xml set $en_name $en_value 56 gui::msgDebug "ENTITY: $en_name || $en_value" 57 } ;# if regexp true 58 } 59 -- { 60 if [regexp {!--(.*)--$} $node_info -> comment] { 61 simxml::add $xml [lindex $nodes_list end] {} -type COMMENT -text $comment 62 gui::msgDebug "COMMENT: $comment" 63 } ;# if 64 } 65 } ;# switch ! TAG NAME 66 if { [string match {[CDATA[*} $tag_name] } { 67 gui::msgDebug "CDATA: ######################################" 68 } ;# match CDATA section 69 set pos [expr $new_pos] 70 continue 71 } 72 / { 73 gui::msgDebug "CLOSE TAG: [string range $node_info 1 end]" 74 set nodes_list [lreplace $nodes_list end end] 75 set pos [expr $new_pos + 1] 76 set action getText 77 continue 78 } 79 } ;# switch FIRST NODE symbol 80 81 if { [string equal [string index $node_info end] {/}] } { 82 set node_info [string range $node_info 0 end-1] 83 foreach { node_name node_attr } [simxml::parseNode $node_info] { break } 84 add $xml [lindex $nodes_list end] $node_name \ 85 -attribute $node_attr -type ELEMENT 86 gui::msgDebug "ELEMENT : $node_name ($node_attr)" 87 incr count_nodes 88 } else { 89 set node_name [ set node_attr {} ] 90 foreach { node_name node_attr } [simxml::parseNode $node_info] { break } 91 lappend nodes_list [add $xml \ 92 [lindex $nodes_list end] $node_name -attribute $node_attr] 93 gui::msgDebug "OPEN TAG: $node_name ($node_attr) \[[join $nodes_list { / }]\]" 94 incr count_nodes 95 } ;# switch LAST NODE symbol 96 97 set buffer {} 98 set pos [expr $new_pos + 1] 99 set action getText 100 gui::msgDebug "##############" 101 } ;# switch --- findXMLend 102 103 getText { 104 set new_pos [string first "<" $source_xml $pos] 105 if { $new_pos == -1 } { set pos $total_length ; continue } 106 107 set buffer [string range $source_xml $pos [expr $new_pos - 1]] 108 regsub -all {^\n} $buffer "" buffer 109 regsub -all {\n$} $buffer "" buffer 110 regsub -all {\s+} $buffer " " buffer 111 if { [string trim $buffer "\t\n "] != "" } { 112 add $xml [lindex $nodes_list end] {} -text $buffer -type TEXT 113 gui::msgDebug "TEXT: |$buffer|" 114 incr count_text 115 } ;# if founded text if not empty 116 117 set pos [expr $new_pos + 1] 118 set action findXMLend 119 } ;# switch --- getText 120 } ;# switch action 121 } ;# Main cycle for Parse XML document 122 123 gui::msgDebug "COUNT NODES: $count_nodes\nCOUNT_TEXT: $count_text" 124 return $xml 125 126