0

私はtDomを使用してXMLをループし、各要素の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]
    }

しかし、空のベンダーを印刷しようとすると、無効なコマンド名""というエラーが発生します。これを無視して$nVendorを空の文字列に設定するにはどうすればよいですか?

4

2 に答える 2

4

ノードのselectNodesメソッドは、パターンに一致するノードのリストを返します。結果をコマンドとして直接使用する場合

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

あなたが実際にやっているのは、1つのアイテム(アイテムの数nameのリストが1つのアイテムと同じであるという事実を利用することです。一致するノードがない場合は、空のリストが返されます

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"
    }
}
于 2010-04-15T13:51:57.027 に答える
2

$nVendorが空のノードであるかどうかを確認できます。

if {$nVendor != ""} {
    puts [$nVendor data]
}
于 2010-04-14T23:07:13.420 に答える