Search code examples
xmlxpathtcltdom

tcl dom get attributes as a list


<Testcases>
<Testcase tc_name="tc1">
  <Parameters>
    <Input_Arguments>tc1_arg1</Input_Arguments>                 
    <Input_Arguments>tc2_arg2</Input_Arguments>
  </Parameters>  
</Testcase>
<Testcase tc_name="tc2">
  <Parameters>
    <Input_Arguments>tc2_arg1</Input_Arguments>
    <Input_Arguments>tc2_arg2</Input_Arguments>
  </Parameters>  
</Testcase>
</Testcases>

Above is my xml, I want to use tdom to first read in all "tc_name" attributes as a tcl list. Then use each tc_name in the list to locate corresponding parameters. Please tell me how to do that, thanks!


Solution

  • Your headline says tcl dom but your question says tdom and it's tagged as tdom so I'll go for a majority decision and give a tdom answer - they are different packages!

    First you need to parse the raw xml with

    # Assumes that xmlText holds your raw XML
    dom parse $xmlText doc
    

    Now get a list of the tc_name nodes

    set nodes [$doc selectNodes {Testcases/Testcase[@tc_name]}
    

    Now cycle around those nodes accessing the Parameter nodes

    foreach node $nodes {
        set params [$node selectNodes Parameters]
        foreach param $params {
            # Do some stuff
        }
    }
    

    Don't forget to get rid of the document once you've finished with it. (Note that this will happen automatically when the proc exits if you're doing it inside a proc.)

    $doc delete
    

    I'm not completely sure what it is you want to do finally, so here's a bit of code to output each argument, with its tc_name, one per line:

    dom parse {<Testcases>
                 <Testcase tc_name="tc1">
                   <Parameters>
                     <Input_Arguments>tc1_arg1</Input_Arguments>                 
                     <Input_Arguments>tc2_arg2</Input_Arguments>
                   </Parameters>  
                 </Testcase>
                 <Testcase tc_name="tc2">
                   <Parameters>
                     <Input_Arguments>tc2_arg1</Input_Arguments>
                     <Input_Arguments>tc2_arg2</Input_Arguments>
                   </Parameters>  
                 </Testcase>
               </Testcases>
            } doc
    foreach testcase [$doc selectNodes Testcases/Testcase] {
        set name [$testcase getAttribute tc_name]
        foreach arg [$testcase selectNodes Parameters/Input_Arguments] {
            foreach child [$arg childNodes] {
                puts stdout $name\ [$child nodeValue]
            }
        }
    }
    $doc delete;          # Tidy away the parsed document
    

    I hope this gives enough pointers to things for you to be able to complete your task