I'm using tDom to loop through some XML and pull out each element's text().
set xml {
<systems>
<object>
<type>Hardware</type>
<name>Server Name</name>
<attributes>
<vendor></vendor>
</attributes>
</object>
<object>
<type>Hardware</type>
<name>Server Two Name</name>
<attributes>
<vendor></vendor>
</attributes>
</object>
</systems>
};
set doc [dom parse $xml]
set root [$doc documentElement]
set nodeList [$root selectNodes /systems/object]
foreach node $nodeList {
set nType [$node selectNodes type/text()]
set nName [$node selectNodes name/text()]
set nVendor [$node selectNodes attributes/vendor/text()]
# Etc...
puts "Type: "
puts [$nType data]
# Etc ..
puts [$nVendor data]
}
But when it tries to print out the Vendor, which is empty, it thows the error invalid command name "". How can I ignore this and just set $nVendor to an empty string?
The selectNodes
method of a node returns a list of nodes that match your pattern. When you use the results directly as a command
set nName [$node selectNodes name/text()]
puts [$nType data]
what you are really doing is taking advantage of the fact that a list of 1 item (the number of name
items) is the same as one item. When there are no matching nodes, you get back an empty list
set nVendor [$node selectNodes attributes/vendor/text()] ;# -> {}
and, when you call that, it's throwing an error because you're calling a command with the name {}
.
set nVendor [$node selectNodes attributes/vendor/text()] ;# -> {}
puts [$nVendor data] ;# -> winds up calling
{} data
As noted by Hai Vu, you can test that there was a result by checking the result against ""
. A "more correct" way would probably be to check it against the empty list
set nVendor [$node selectNodes attributes/vendor/text()]
if {[llength $nVendor] == 1} {
puts [$nVendor data]
}
or, to be even more complete (if you're not sure about the input XML)
set nVendor [$node selectNodes attributes/vendor/text()]
switch -exact -- [llength $nVendor] {
0 {
# no nVendor, do nothing
}
1 {
# 1 vendor, print it
puts [$nVendor data]
}
default {
# weird, we got more than one vendor node... throw an error
error "More than one vendor node"
}
}