Formal metadata information and software
C:\Tcl
C:\USGS
.
cd C:\USGS\tools\bin copy mq26.dll C:\Tcl\lib mkdir C:\Tcl\lib\mq copy pkgIndex.tcl C:\Tcl\lib\mq
C:\> tclsh % puts "Hello, World!" Hello, World! % expr 2 + 2 4 % expr 355.0 / 113 3.14159292035 % exit(To quit the Tcl interpreter, enter "
exit
"; "quit
" doesn't do it.)
[like this]
gets executed and is replaced by its
result. So in the example puts "Have some [expr 355.0 / 113]"
,
the text between the braces is replaced by "3.14159292035", and that
statement prints Have some 3.14159292035. See the Tcl
Tutorial at http://www.tcl.tk/man/tcl8.5/tutorial/tcltutorial.html;
there are a number of good books on Tcl as well.
metadata m -parse c:/USGS/tools/doc/metadata/mp.metReturns 1 if mq managed to find and read the metadata record, 0 otherwise. So you can write
if {[metadata m -parse c:/USGS/tools/doc/metadata/mp.xml]} { # do some things with this record }Notice that in this case I'm reading the XML version of the file; like mp, mq can read indented text or XML or SGML. Notice also that we use forward slashes for directory separators, not backslashes (use
/
instead of \
).
If this works, we use the variable m
to work with the metadata.
For example, to find the Identification_Information, we write
$m find_first Identification_InformationWhat we get from this is the address of the Identification_Information. Normally we need to store that address in a variable:
set p [$m find_first Identification_Information]We don't manipulate that address directly, but we pass it to other mq functions, for example, to find an element within another:
set q [$m find_in $p Cross_Reference]This will return the address of the first Cross_Reference element within the element
p
; the address of the Cross_Reference element is stored in
the variable q
.
set p [$m find_first Identification_Information] if {$p} { set q [$m find_in $p Cross_Reference] }Since the Tcl
set
command returns the value you're setting, you can use
it as a test in an if
statement. This produces a more compact form:
if {[set p [$m find_first Identification_Information]]} { if {[set q [$m find_in $p Cross_Reference]]} { # do something with the cross reference that is now in q } }To get one of the element's values:
if {[set p [$m find_first Access_Constraints]]} { # Get the text of Access_Constraints, store in variable t set t [$m value_of $p] # print the value puts "$t" }To set an element's value:
if {[set p [$m find_first Access_Constraints]]} { # Set the text of Access_Constraints to "None" $m value_set $p "None" }If you've made changes and you want to keep them,
write
the file. If you
don't specify a file name, mq overwrites the original file. You can save
the data in a format different from the one you read (so mq can be used to
convert from indented text to XML and back again).
$m write $m write my_copy.xmlWhen you're working with many files, don't keep track of them all at once unless you really have to; instead,
forget
about each one as soon as
you're done getting information from it:
$m forgetThere are many more operations you can carry out on metadata. See mq's reference manual for a complete list.
# Open the metadata record metadata m -parse C:/USGS/tools/doc/metadata/mp.met # Find the Citation if {[set p [$m find_first Citation]]} { # Find the title within the Citation. if {[set q [$m find_in $p Title]]} { # Get the value of the title and print it out. set t [$m value_of $q] puts "$t" } \ else { # If no Title exists, complain. puts "This record has no title." } } # When done, forget about this record. $m forget
# Open the metadata record metadata m -parse C:/data/catfish.xml # Find the Keywords section. There's only one of these. if {[set p [$m find_first Keywords]]} { # Look for Place within Keywords. This can be repeated. if {[set q [$m find_in $p Place]]} { # If there is one Place, there may be more of them. while {$q} { # Find and print the Place_Keyword_Thesaurus, if any if {[set r [$m find_in $q Place_Keyword_Thesaurus]]} { # Get the value and print it out. set t [$m value_of $r] puts "Place terms from thesaurus $t" } \ else { puts "No Place_Keyword_Thesaurus within this Place!" } # Look for Place_Keywords within this Place. Repeats. set u [$m find_in $q Place_Keyword] while {$u} { # Get the value and print it out. set t [$m value_of $u] puts " $t" # Find the next Place_Keyword. set u [$m find_next $u] } # Find the next Place section set q [$m find_next $q] } } } # When done, forget about this record. $m forget
proc process_directory {long_name short_name} { recurse $long_name } proc process_file {long_name short_name} { if {[string compare [file extension $short_name] .met] == 0} { # operations on each metadata record go here } } proc recurse {dir} { global root foreach long_name [lsort [glob [file join $dir *]]] { scan $long_name "$root/%s" short_name if {[file isdirectory $long_name]} { process_directory $long_name $short_name } \ else { process_file $long_name $short_name } } } set root [pwd] set short_name . recurse $root
Peter N. Schweitzer Mail Stop 954, National Center U.S. Geological Survey Reston, VA 20192 Tel: (703) 648-6533 FAX: (703) 648-6252 Email: pschweitzer@usgs.gov