XML Clean-Up

David Bigelow:

I was working with xmlgen-1.4 and had quite a bit of success with it.

However, formatting of the results seemed to be a real pain, and the documentation, examples, discussion thread, direct discussions with the originator of xmlgen did not seem to help me grasp the issues. From what I could tell, others in the community were having similar issues.

So to get my job done, I wrote the following routine. (Don't laugh - it could be better, but time has not been on my side.)

The following code does a very nice job of structuring resulting XML. I hope you find it as useful as I have.


[CleanUP] needs the string of XML that will be cleaned up as the submission variable. This application generates a textbox to display the results.

Code

### XML CLEANUP ROUTINES

proc placeData {indentlevel item} {
    set tabs ""
    set i 1
    while {$i <= $indentlevel} {
        lappend tabs "\t"
        incr i
    }
    if {[llength $item] > 0 } {
        # Write data to the non-visible textbox
        .tb2 insert end "[join $tabs]$item\n"
    }
} ; # end placeData


proc CleanUp {xml} {
    catch {destroy .tb2}
    text .tb2
    
    # Gather XML Content
    set indentlevel 0
    foreach item [split $xml \n] {
        set item [string trim $item]
        switch -glob -- $item {
            <?xml* {
                # Header -- NO indent Adjustment
                placeData $indentlevel $item
            }
            */> {
                # Handle NULL Value Tags
            }
            </* {
                # End Tag
                incr indentlevel -1
                placeData $indentlevel $item
            }
            <* {
                # Look for tags on the same line verses start of a XML nest structure
                # Get the tag name
                regsub -all {<|>} $item { } tempitem
                set tag [lindex $tempitem 0]
                if [string match *</$tag> $item] {
                    # In-Line Tag - NO indent Adjustment
                    placeData $indentlevel $item
                } else {
                    # Tag is head of a super structure
                    placeData $indentlevel $item
                    incr indentlevel
                }
            }
        } ; # end switch
    } ; # end foreach
    return [.tb2 get 0.0 end]
} ; # end CleanUp

In the future, I would like to add more controls to toggle between tab indentions verses spaces. And also possibly eliminate the second process and keep it all in one proc.

Hope you get as much benefit from this as I have.