Search code examples
xmlparsingtcltdom

TCL TDom: Looping through Objects


Using TDom, I would like to cycle through a list of objects in the following format:

    <object>
      <type>Hardware</type>
      <name>System Name</name>
      <description>Basic Description of System.</description>
      <attributes>
          <vendor>Dell</vendor>
          <contract>MM/DD/YY</contract>
          <supportExpiration>MM/DD/YY</supportExpiration>
          <location>Building 123</location>
          <serial>xxx-xxx-xxxx</serial>
          <mac>some-mac-address</mac>
      </attributes>
    </object>

    <object>
      <type>Software</type>
      <name>Second Object</name>
    ...

Then I use TDom to make a list of objects:

set dom [dom parse $xml]
set doc [$dom documentElement]

set nodeList [$doc selectNodes /systems/object]

So far I've done this to (theoretically) select every "Object" node from the list. How can I loop through them? Is it just:

foreach node $nodeList { 

For each object, I need to retrieve the association of each attribute. From the example, I need to remember that the "name" is "System Name", "vendor" is "Dell", etc.

I'm new to TCL but in other languages I would use an object or an associative list to store these. Is this possible? Can you show me an example of the syntax to select an attribute in this manner?


Solution

  • You are indeed on the right track. You probably want to do this:

    foreach node [$doc selectNodes "/systems/object"] {
        set name [[$node selectNodes "./name\[1\]"] text]
        lappend listOfNames $name
        foreach attr {vendor serial} {
            set aNodes [$node selectNodes "./attributes/$attr"]
            if {[llength $aNodes]} {
                set data($name,$attr) [[lindex $aNodes 0] text]
            }
        }
    }
    

    I'm using Tcl's (associative) array capabilities to hold the extracted attributes. There are other ways that will also work, e.g., an iTcl or XOTcl or TclOO object, or a dictionary, or any number of other possibilities. Mind you, I'd actually be tempted to keep the document itself around and process directly off that, given how easy it is to actually work with tDOM; no need to extract everything into some other data structure just for the heck of it.