This is an operation you could do with a text editor or many of the typical metadata editors like Tkme. But it's mindless in the sense that you can specify the steps exactly, and it doesn't require you to think specifically about each record beyond following the procedure.
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
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]
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