TCL tDom空XML标记

时间:2010-04-14 19:14:34

标签: xml parsing xpath tcl tdom

我正在使用tDom来遍历一些XML并提取每个元素的文本()。

    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]
    }

但是当它试图打印出供应商时,它是空的,它会使错误无效的命令名称“”。如何忽略这一点并将$ nVendor设置为空字符串?

2 个答案:

答案 0 :(得分:4)

节点的selectNodes方法返回与您的模式匹配的节点列表。将结果直接用作命令时

set nName  [$node selectNodes name/text()]
puts [$nType data] 

你真正在做的是利用1项name项的数量)的列表与一项相同的事实。如果没有匹配的节点,则会返回一个空列表

set nVendor [$node selectNodes attributes/vendor/text()]  ;# -> {}

并且,当你调用它时,它会抛出一个错误,因为你正在调用一个名为{}的命令。

set nVendor [$node selectNodes attributes/vendor/text()]  ;# -> {}
puts [$nVendor data]  ;# -> winds up calling
{} data

如Hai Vu所述,您可以通过针对""检查结果来测试结果。 “更正确”的方法可能是在空列表中检查它

set nVendor [$node selectNodes attributes/vendor/text()]
if {[llength $nVendor] == 1} {
    puts [$nVendor data]
}

或者,更完整(如果您不确定输入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"
    }
}

答案 1 :(得分:2)

您可以检查$ nVendor是否为空节点:

if {$nVendor != ""} {
    puts [$nVendor data]
}