[Arjen Markus] 2009-09-08: I often use simple commands as a way to configure a
program or to read data. [[`[source]`] then suffices to interpret the
configuration or data. I wondered whether it would be possible to use the so
popular XML format to do the same. Of course, things are not so
straightforward, but here is a first (admittedly playful) attempt.
Take the following XML file:
======
"Value is $var"
======
The trained eye will recognise a lot of Tcl commands in the guise of tags. That is exactly
what is meant. Here is the code to interpret it:
======
# xmlsource.tcl --
# Read an XML file and convert it on the fly to Tcl code
#
package require tdom
set infile [open "example.xml" r]
set contents [read $infile]
close $infile
dom parse $contents code
$code documentElement root
foreach commandNode [$root childNodes] {
set cmd [$commandNode nodeName]
if { $cmd eq "set" } {
foreach arg [$commandNode attributes] {
set $arg [$commandNode getAttribute $arg]
}
} elseif { ![$commandNode hasChildNodes] && [$commandNode nodeType] eq "ELEMENT_NODE" } {
set argv {}
foreach arg [$commandNode attributes] {
append argv [$commandNode getAttribute $arg]
}
eval $cmd [list $argv]
} else {
if { [$commandNode nodeType] eq "ELEMENT_NODE" && [llength [$commandNode childNodes]] == 1 } {
#
# Assume simple command
#
set cmd [$commandNode nodeName]
set argv [[$commandNode childNodes] nodeValue]
eval $cmd $argv
} else {
puts "Complex commands not implemented yet"
}
}
}
======
Run this program and you will see some of the possibilities and the
limitations.
Essentially: You can put Tcl commands inside XML files, so that people who are
used to handling XML files can continue doing so, without you having to do more
than identifying what the most convenient way is to handle the various kinds of
commands.
An extension to the above would be:
======
proc rootFindingMethod {name tolerance} {
set ::methodUse $name
set ::numericalTolerance $tolerance
}
======
and in the XML file (the interpreting code will have to match the attributes and arguments by name, but that
can be made completely generic):
======
Newton-Raphson
1.0e-6
======
<> Category XML