TCL tDom Пустой тег XML - PullRequest
       15

TCL tDom Пустой тег XML

0 голосов
/ 14 апреля 2010

Я использую 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]
    }

Но когда он пытается распечатать Vendor, который пуст, он выдает ошибку недопустимое имя команды "". Как я могу игнорировать это и просто установить $ nVendor на пустую строку?

Ответы [ 2 ]

4 голосов
/ 15 апреля 2010

Метод 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

Как отметил Хай Ву, вы можете проверить, что был результат, сравнив результат с "".«Более правильным» способом, вероятно, было бы проверить его по пустому списку

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"
    }
}
2 голосов
/ 15 апреля 2010

Вы можете проверить, является ли $ nVendor пустым узлом:

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