Because of the enormous amount of duplication in XSD files, writing them by hand to can be very tedious. There are tools to reduce the pain, but they are usually quite expensive and still require quite a bit of manual work. [MJ] - I have written a small [DSL] in Tcl to automate the largest part of creating an XSD. I call it TSD for Tcl Schema Definition The DSL is fairly straightforward For example this tsd file: ====== text {} text {} define root item+ define item { part1! part2? part3 } define part1 xsd:string define part2 xsd:decimal {This is optional} extension part3 xsd:normalizedString {{attr1 {this is attr1}}} { Complex stuff } text "" ====== will be translated to: ====== This is optional Complex stuff this is attr1 ====== The script: === package require Tcl 8.5 package require tdom proc define {element sequence {documentation {}}} { if { [llength $sequence] == 1 && [string range $sequence 0 3] eq "xsd:" } { emitElement $element $sequence $documentation return } set typename ${element}Type emitElement $element $typename emitTypeDef $typename $sequence $documentation } proc extension {element baseType attributes {documentation {}}} { emit [subst { $documentation }] foreach attribute $attributes { lassign $attribute name doc emit [ subst { $doc }] } emit { } } proc text text { emit $text\n } proc include {filename} { set f [open $filename] fconfigure $f -encoding utf-8 emit \n[read $f]\n close $f } proc emitElement {element type {documentation {}}} { if {$element eq {}} { set cardinality {} switch -- [string index $type end] { + { set type [string range $type 0 end-1 ] set cardinality {minOccurs="1" maxOccurs="unbounded"} } ? { set type [string range $type 0 end-1 ] set cardinality {minOccurs="0" maxOccurs="1"} } ! { set type [string range $type 0 end-1 ] set cardinality {minOccurs="1" maxOccurs="1"} } } emit "\n" } { emit "\n" } if {$documentation ne {}} { emit "\n" emit "$documentation\n" emit "\n" } emit "\n" } proc emitSequence {sequence} { emit "\n" foreach item $sequence { emitElement {} $item } emit "\n" } proc emitTypeDef {type sequence documentation} { emit "\n" if {$documentation ne {}} { emit "\n" emit "$documentation\n" emit "\n" } emitSequence $sequence emit "\n" } proc emit text { # This is used to emit the generated xsd text. Redefine this to match your usecase. error "You'll need to override emit" } proc beautify {xml} { set xml "\n[[dom parse $xml] asXML -indent 2]" } # ================================ # redefine emit to do the right thing proc emit {text} { append ::result $text } if {$argc < 1 || $argc > 2} { puts stderr "Usage: tsd2xsd tsd-file ?xsd-file?" exit } set path [pwd] cd [file dirname [lindex $argv 1]] lassign $argv tsd xsd source -encoding utf-8 $tsd if {$xsd ne {} } { set f [open $xsd w] fconfigure $f -encoding utf-8 } else { set f stdout } if {[catch {puts $f [beautify $result]} error]} { puts stderr $errorInfo puts $f $result } close $f cd $path ===