Posted to tcl by pooryorick at Tue Aug 27 18:37:37 GMT 2019view raw
- #! /usr/bin/env tclsh
- package require tdom
- dom createDocumentNS urn://ns1 ns1:doc root
- $root documentElement doc
- $doc setAttributeNS {} xmlns:ns1 urn://ns1
- dom createDocument doc root2
- $root2 documentElement doc2
- $root2 createElement ns1:tag1 one
- $doc appendChild $one
- set node [lindex [$doc selectNodes ns1:tag1] 0]
- puts [list selected $node]
Comments
Posted by de at Tue Aug 27 21:27:39 GMT 2019 [text] [code]
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.)