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