TclDOM

TclDOM is the DOM part of Explain's TclXML project.

Attributes

website
http://tclxml.sourceforge.net/
release time
< 2008-12
Contact
Steve Ball

See Also

TclDOM vs tDOM

Documentation

official reference

Examples

Get an XPath location path from a DOM node
XSD schema validate an XML document
tkxmllint
uses TclDOM/libxml2. Examples of getelementsByTagName, etc.

Widgets

DOM related megawidgets
text-based DOMText , and BWidget-based TreeDOM

Description

TclDOM, a component of TclXML, is a binding for the Document Object Model. TclDOM features live node lists and named node maps.

TclDOM has partial pure-Tcl-coded XPath support (since 2001-09).

Version 2.5 of TclDOM adds a couple of new example scripts that may be useful:

domtext
displays a DOM document in a Tk Text widget
domtree
displays a DOM document's tree structure in a BWidget Tree widget.

Version 3.0 includes the source script for tkxmllint (http://tclxml.sourceforge.net/tkxmllint.html ) application.


Andreas Kupries provides a daily snapshot of the SourceForge CVS depot at http://www.purl.org/net/akupries/soft/cvs-snapshots/ .

AK: Note: There are ways of Getting Tcl/Tk other than my site.

SRB: Most recent TclDOM distributions provide Mac OS X and MS Windows binaries.

ActiveState's ActiveTcl provides the ability to use this package - after installing an ActiveTcl of 8.4.something or newer, read up on the teacup command for the method of adding additional extension packages.


PT: If you are trying to load TclDOM into a safe slave interpreter see the notes under TclXML


Steve Ball: "The only software in the TclXML stable that will validate a document is TclDOM/libxml2.". This package is also known as Tcldomxml. It wraps a TclDOM-API around GNOME's libxml2 [L1 ] and provides the basis for TclXSLT.

Version 3.0 provides XML Schema and RelaxNG validation, in addition to DTD validation.


CThatcher: TclDOM seems to be missing a few important features - like the ability to parse new data into an arbitrary place in a DOM document. The only parse feature creates a new document each time and most of the ::node:: operations (like appendChild) simply complain that the node needs to be in the same document. If anyone knows a quick and easy way to do the above with TclDOM please let me know.

Steve Ball: (Updated) DOM Level 3 introduces an "importNode" method that solves this problem. This has been implemented in TclDOM/tcl v3.0b2 (an implementation for TclDOM/libxml2 is on the TODO list).

CThatcher: Additionally, there should at least be an option for parsing that allows us to control the underlying parser before parsing actually takes place. Like the handling of whitespace. In *theory* we should be treating all whitespace as is, but in practice we need to be a little more brutal than that sometimes - and, let's face it, the trim function is diabolically slow.

Steve Ball: How about submitting an RFE to the TclXML SourceForge tracker? (Update: The TclDOM parse method (as of version 3.0b2) passes arguments through to the TclXML parser, so enabling/disabling ignorable-whitespace can be done)

CThatcher: Ok, thanks Steve; I'll stop ranting and start helping. Is there a tech document on how all the DOM structures work together internally, etc., as I may look into implementing importNode myself, but I'm lazy and don't want to spend hours of trawling the source :)

Steve Ball: Hmmm... no there isn't any technical doco. I'll put that on my to-do list.


lv: there is something called tcldompro - is this an obsolete package? Does it provide functionality that is no longer needed or has been deprecated in favor of some other package?

Steve Ball: "tcldompro" is a C implementation of the TclDOM API. It is included in the TclDOM distribution (in the "src" directory), but not built by default. Originally written by Al Biggerstaff (when at Ajuba Solutions), it is currently maintained by Joe English.


Windows might require

package require xml
package require xml::libxml2
package require dom

to load the package correctly.


Several aspects of TclDOM's documentation haven't kept pace with the package itself. Miscellaneous observations:

  • "The -attributes option of the node command gives you the name of a Tcl array (ie. it's a 'live' variable) that contains the attribute names and values."
  • ...

Steve Ball 2006-11-29: I just checked the v3.1 documentation online at tclxml.sf.net and it correctly documents the -attributes option.


This code will validate an XML document using a schema file.

set fd [open "foo.xml"]
set xml_instance [read $ch]
close $fd
set doc [dom::parse $xml_instance] ;# this is the instance XML document
set fd [open "foo.xsd"]
set schemaxml [read $fd]
close $fd
set schemadoc [dom::parse $schemaxml]       ;# this is the schema XML document
$schemadoc schema compile
if {[catch {$schemadoc schema validate $doc} msg]} {
    puts stderr "document is not schema-valid due to \"$msg\""
} else {
    puts stderr "document is schema-valid"
}

Anyone know how compatibility is with Tcl 8.5.x?

DrASK I'm thinking not good, here's what happens to me:

% info patchlevel
8.5.4
% package require dom
attempt to provide package sgmlparser 1.1 failed: package sgmlparser 1.0 provided instead
% package present dom
package dom is not present

SRB 2008-12-17: TclXML v3.2 has been built and tested against Tcl 8.5.5.

SRB 2009-07-13: TclXML v3.3 (not yet released) has been built and tested against Tcl 8.6b2.


cokh 2012-05-27 10:31:35:

<How do I keep ALL of the original comments and print with the original newlines?>


How can I catch a parse error? dom::parse gives a segmentation fault when the XML doc is invalid (like a missing '<').

$ tclsh
% package require xml
3.2
% set xmlstr "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Node/>"
<?xml version="1.0" encoding="UTF-8"?><Node/>
% set doc [dom::parse $xmlstr]
doc0
% set xmlstr "<?xml version=\"1.0\" encoding=\"UTF-8\"?>Node/>"
<?xml version="1.0" encoding="UTF-8"?>Node/>
% set doc [dom::parse $xmlstr]
Segmentation fault

I haven't found how to use -parser tcl yet. Any clues?

I have a server project where the server receives an XML doc via TCP socket, and spews out a slightly modified XML doc (with additional nodes) to clients every 200ms. My idea was to parse the original XML doc to a TclDOM doc, then clone the document node and append this to a newly created document, and add the new information before sending to connected clients. After sending, destroy the new doc before the next 200ms. Trouble is, in libxml there is a segv with null pointer free. Now looking at tDOM.


MHo 2016-05-03: This script works with tclsh, but not with wish (under MS Windows); why?

package require dom
set xml [lindex $argv 0]
set i [open $xml r]
set buf [read $i]
close $i
set root [::dom::DOMImplementation parse $buf]
set ret [::dom::DOMImplementation selectNode $root /Document/CstmrCdtTrfInitn/PmtInf/DbtrAcct/Id/IBAN/text()]
puts [::dom::node cget [lindex $ret 0] -nodeValue]

Addition: xPath-Query does not work at all; don't know why... only after removing the xml-Header from the file...