I found properly creating new elements in an XML document using tDOM a challenge. After some help in the Tcl chat I was shown a few working solutions.
Using createElementNS
package require tdom
set xml {<ns1:Root xmlns="http://default.com" xmlns:ns1="http://some.otherns.com">
<ns1:Item>Here be text</ns1:Item>
</ns1:Root>}
dom parse $xml doc
set root [$doc documentElement]
set item [$doc createElementNS http://some.otherns.com ns1:Item]
set text [$doc createTextNode "other text"]
$item appendChild $text
$root appendChild $item
puts [$root asXML]
<ns1:Root xmlns="http://default.com" xmlns:ns1="http://some.otherns.com/">
<ns1:Item>Here be text</ns1:Item>
<ns1:Item>other text</ns1:Item>
</ns1:Root>
Using appendFromScript
I find this option more elegant as it’s much more ergonomic in use. It’s almost like a DSL to create XML chunks.
package require tdom
set xml {<ns1:Root xmlns="http://default.com" xmlns:ns1="http://some.otherns.com">
<ns1:Item>Here be text</ns1:Item>
</ns1:Root>}
dom parse $xml doc
dom createNodeCmd -namespace http://some.otherns.com element ns1:Item
dom createNodeCmd textNode t
set root [$doc documentElement]
$root appendFromScript {
ns1:Item {t Othertext}
}
puts [$root asXML]
<ns1:Root xmlns="http://default.com/" xmlns:ns1="http://some.otherns.com/">
<ns1:Item>Here be text</ns1:Item>
<ns1:Item>Othertext</ns1:Item>
</ns1:Root>
Note
The previous version of this post used $doc childNodes
to get the root element of the dom tree. This usually works, but the correct way is to use $doc documentElement
. Observe the difference in the script below:
package require tdom
set xml "<a/><!-- Comment -->"
set doc [dom parse $xml]
puts "WRONG: [$doc childNodes]"
puts "GOOD: [$doc documentElement]"
Which prints:
WRONG: domNode0x7f738c43ebb0 domNode0x7f738c43ec10
GOOD: domNode0x7f738c43ebb0