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