[AMG]: [Coroutine]s are especially well suited to parsing XML in [SAX] mode, i.e. as a stream of events. Here's one way to do it with [tDOM]: ====== # parseXmlFile -- # Parses an XML file using the supplied event dispatch table. # Source: http://wiki.tcl.tk/49298 proc parseXmlFile {dispatch filename args} { # Create parser coroutine. for {set i 0} {[info commands [set coro ::Parse$i]] ne {}} {incr i} {} coroutine $coro apply {{Dispatch} { while {1} { # Yield to the Expat parser, which will invoke this coroutine again # the next time a registered event occurs. The return value of # [yieldto] will be the event type and arguments. set Args [lrange [set Key [yieldto return -level 0]] 1 end] # Run all applicable event handlers, starting with most specific. for {} {$Key ne {}} {set Key [lreplace $Key end end]} { if {[dict exists $Dispatch $Key]} { lassign $Args {*}[lindex [dict get $Dispatch $Key] 0] eval [lindex [dict get $Dispatch $Key] 1] } } } }} $dispatch # Create Expat parser and glue to the parser coroutine. set parser [expat] foreach event [lsort -unique [lmap i [dict keys $dispatch] {lindex $i 0}]] { if {[string index $event 0] eq "-"} { $parser configure $event [list $coro $event] } } # Enable TNC to automatically validate against DTD schema. catch {tnc $parser enable} # Initialize parser coroutine. if {[dict exists $dispatch initialize]} { $coro initialize $filename {*}$args } # Run Expat parser, which will exercise the coroutine. $parser parsefile $filename $parser free # Finalize parser coroutine. if {[dict exists $dispatch finalize]} { return [$coro finalize] } else { rename $coro {} } } ====== Examples to come. <> XML | Parsing | Control Structure