I have this XML
sample template from a command line output,
<config xmlns="http://tail-f.com/ns/config/1.0">
<random xmlns="http://random.com/ns/random/config">
<junk-id>1</junk-id>
<junk-ip-address>1.2.2.3</junk-ip-address>
<junk-state>success</junk-state>
<junk-rcvd>158558</junk-rcvd>
<junk-sent>158520</junk-sent>
<foobar>
<id1>1</id1>
<id2>1</id2>
</foobar>
</random>
</config>
I need to extract the value of junk-state
from this XML
.
I made a .tcl
script to run on this with a variable and using single quotes just for testing purposes as below,
Below are contents of my script. I just tried looping around the nodes, but with no success.
set XML "<config xmlns='http://tail-f.com/ns/config/1.0'>
<random xmlns='http://random.com/ns/random/config'>
<junk-id>1</junk-id>
<junk-ip-address>1.2.2.3</junk-ip-address>
<junk-state>success</junk-state>
<junk-rcvd>158558</junk-rcvd>
<junk-sent>158520</junk-sent>
<foobar>
<id1>1</id1>
<id2>1</id2>
</foobar>
</random>
</config>"
set doc [dom parse $XML]
set root [$doc documentElement]
set mynode [$root selectNodes "/config/random" ]
foreach node $mynode{
set temp1 [$node text]
echo "temp1 - $temp1"
}
The above script produces no output,
Also tried a direct xpath
expression as below and print text
set node [$root selectNodes /config/random/junk-state/text()]
puts [$node nodeValue]
puts [$node data
and this produces an error
invalid command name ""
while executing
"$node nodeValue"
invoked from within
"puts [$node nodeValue]"
(file "temp.tcl" line 41)
What am I doing wrong here. Like to know how use/modify my xpath
expression, since I find that neater.
$ tclsh
% puts $tcl_version
8.5
% package require tdom
0.8.3
The problems are due to the XML namespaces (xmlns
attributes in the config
and random
elements). You must use the -namespace
option of selectNodes
operation:
package require tdom
set XML {<config xmlns="http://tail-f.com/ns/config/1.0">
<random xmlns="http://random.com/ns/random/config">
<junk-id>1</junk-id>
<junk-ip-address>1.2.2.3</junk-ip-address>
<junk-state>success</junk-state>
<junk-rcvd>158558</junk-rcvd>
<junk-sent>158520</junk-sent>
<foobar>
<id1>1</id1>
<id2>1</id2>
</foobar>
</random>
</config>}
set doc [dom parse $XML]
set root [$doc documentElement]
set node [$root selectNodes -namespace {x http://random.com/ns/random/config} x:random/x:junk-state ]
puts [$node text]
EDIT: If you want the namespace of the <random>
element to be retrieved from the XML automatically you can do it as follows (assuming that <random>
is the only child of the root element):
set doc [dom parse $XML]
set root [$doc documentElement]
set random [$root childNode]
set ns [$random namespace]
set node [$random selectNodes -namespace [list x $ns] x:junk-state]
puts [$node text]