Posted to tcl by de at Tue Aug 27 21:34:31 GMT 2019view pretty

package require tdom

# Lemme comment and (try to) explain step by step.

# With createDocumentNS you create a XML namespaces aware document.
# (Both the w3c XML recommendation and the w3c XML Namespaces
# recommendation come into play.)
dom createDocumentNS urn://ns1 ns1:doc root
$root documentElement doc

# Side note: Your variable naming is unorthodox and probably confusing
# to the reader. See:
puts "root is [$root nodeType]"
puts "doc is [$doc nodeType]"

# Your following line of code is completely unnecessary. To
# demonstrate, let's comment it out ..
# $doc setAttributeNS {} xmlns:ns1 urn://ns1
# ... and do instead this:
puts [$root asXML]
# This generates:
# <ns1:doc xmlns:ns1="urn://ns1"/>
# You see that the createDocumentNS automagically has created the
# necessary xmlns declaration by it's own.

# With the following you create a DOM 1 (plain w3c XML recommendation)
dom createDocument doc root2
$root2 documentElement doc2

# With this you create also a DOM 1 (not XML namespaces aware) node,
# even if you think, this node has a namespace "prefix". It hasn't.
# The w3c XML recommendation allows element names with colons in it
# (and not meaning anything like "prefix" with that, this semantic
# level is added by the XML Namespaces recommendation.
$root2 createElement ns1:tag1 one
# Let us confirm what I wrote with introspection:
puts "one - local name: [$one localName]"
puts "one - namesspace URI: [$one namespaceURI]"
puts "one - prefix: [$one prefix]"
# All three output lines show nothing after the ":". (You may find
# this debatable for the localName method result, but let us put that
# aside, for now.)
#
# For contrast look at the output for the namespaced node from your
# first document, that you have stored in the a bit confusing named
# variable doc:
puts "doc - local name: [$doc localName]"
puts "doc - namesspace URI: [$doc namespaceURI]"
puts "doc - prefix: [$doc prefix]"

# With the following you are mixing namespaced and non-namespaced
# nodes. While this works on a technical level, this may have all kind
# of bizarr effects on semantical level.
$doc appendChild $one

# One (at least for me) not so surpsing result of mixing namespace
# nodes with non namespaced nodes is this:
set node [lindex [$doc selectNodes ns1:tag1] 0]
puts [list selected $node]
# There's no node selected; that's the right result. The selectNodes
# method implements the namespace aware XPath 1.0. You query for nodes
# in the urn://ns1 namespace (the prefix ns1 in the XPath expression
# points to that). But the node $one which you've moved to be a child
# of $doc isn't in any namespace - see above, we've checked this.

# It's not clear to me, what are the higher level goals of your
# maneuvers. It seems to me, you want to modify the namespace of a
# node (for whatever reason). But you can't do this; the namespace of
# a node is immutable. As the name of a node is. A node with a
# different name or a different namespace is obviously (semantically)
# something else. If you want to remove some contente then ... just
# remove it. If you want to add some new elements, create them with
# the name and namespace you need and add them. There's no point in
# creating nodes with some name/namespace and later somehow modify
# them to other names/namespaces. Or at least the whole XML world
# hasn't any concept of that.
#
# Baseline: name and namespace of a node are immutable.
#
# (Well, with tDOM, being such a kitchen sink, you can cheat a bit:
# there's the renameNode method. With that you are in fact able to
# change the name of a node. But there's nothing to change the
# namespace of a node. And please: you'd better don't use renameNode.
# Surprising results are lurking for the naive eye.)

Comments

Posted by pooryorick at Wed Aug 28 07:12:28 GMT 2019 [text] [code]

Yes, I'm aware of each and every thing you've explained. I only attempted appendChild in my example because you suggested using it earlier when I stated that my goal was to create a node in the proper namespace, resolving the namespace prefix for the new node in the context of its soon-to-be parent. So it seems still that there isn't a way to do this in tdom. It can by done with my namespace-aware implementation of appendFromList, at http://chiselapp.com/user/pooryorick/repository/tdomutil, which resolves any namespace prefixes in in the context of the prospective parent node.