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

  1. package require tdom
  2.  
  3. # Lemme comment and (try to) explain step by step.
  4.  
  5. # With createDocumentNS you create a XML namespaces aware document.
  6. # (Both the w3c XML recommendation and the w3c XML Namespaces
  7. # recommendation come into play.)
  8. dom createDocumentNS urn://ns1 ns1:doc root
  9. $root documentElement doc
  10.  
  11. # Side note: Your variable naming is unorthodox and probably confusing
  12. # to the reader. See:
  13. puts "root is [$root nodeType]"
  14. puts "doc is [$doc nodeType]"
  15.  
  16. # Your following line of code is completely unnecessary. To
  17. # demonstrate, let's comment it out ..
  18. # $doc setAttributeNS {} xmlns:ns1 urn://ns1
  19. # ... and do instead this:
  20. puts [$root asXML]
  21. # This generates:
  22. # <ns1:doc xmlns:ns1="urn://ns1"/>
  23. # You see that the createDocumentNS automagically has created the
  24. # necessary xmlns declaration by it's own.
  25.  
  26. # With the following you create a DOM 1 (plain w3c XML recommendation)
  27. dom createDocument doc root2
  28. $root2 documentElement doc2
  29.  
  30. # With this you create also a DOM 1 (not XML namespaces aware) node,
  31. # even if you think, this node has a namespace "prefix". It hasn't.
  32. # The w3c XML recommendation allows element names with colons in it
  33. # (and not meaning anything like "prefix" with that, this semantic
  34. # level is added by the XML Namespaces recommendation.
  35. $root2 createElement ns1:tag1 one
  36. # Let us confirm what I wrote with introspection:
  37. puts "one - local name: [$one localName]"
  38. puts "one - namesspace URI: [$one namespaceURI]"
  39. puts "one - prefix: [$one prefix]"
  40. # All three output lines show nothing after the ":". (You may find
  41. # this debatable for the localName method result, but let us put that
  42. # aside, for now.)
  43. #
  44. # For contrast look at the output for the namespaced node from your
  45. # first document, that you have stored in the a bit confusing named
  46. # variable doc:
  47. puts "doc - local name: [$doc localName]"
  48. puts "doc - namesspace URI: [$doc namespaceURI]"
  49. puts "doc - prefix: [$doc prefix]"
  50.  
  51. # With the following you are mixing namespaced and non-namespaced
  52. # nodes. While this works on a technical level, this may have all kind
  53. # of bizarr effects on semantical level.
  54. $doc appendChild $one
  55.  
  56. # One (at least for me) not so surpsing result of mixing namespace
  57. # nodes with non namespaced nodes is this:
  58. set node [lindex [$doc selectNodes ns1:tag1] 0]
  59. puts [list selected $node]
  60. # There's no node selected; that's the right result. The selectNodes
  61. # method implements the namespace aware XPath 1.0. You query for nodes
  62. # in the urn://ns1 namespace (the prefix ns1 in the XPath expression
  63. # points to that). But the node $one which you've moved to be a child
  64. # of $doc isn't in any namespace - see above, we've checked this.
  65.  
  66. # It's not clear to me, what are the higher level goals of your
  67. # maneuvers. It seems to me, you want to modify the namespace of a
  68. # node (for whatever reason). But you can't do this; the namespace of
  69. # a node is immutable. As the name of a node is. A node with a
  70. # different name or a different namespace is obviously (semantically)
  71. # something else. If you want to remove some contente then ... just
  72. # remove it. If you want to add some new elements, create them with
  73. # the name and namespace you need and add them. There's no point in
  74. # creating nodes with some name/namespace and later somehow modify
  75. # them to other names/namespaces. Or at least the whole XML world
  76. # hasn't any concept of that.
  77. #
  78. # Baseline: name and namespace of a node are immutable.
  79. #
  80. # (Well, with tDOM, being such a kitchen sink, you can cheat a bit:
  81. # there's the renameNode method. With that you are in fact able to
  82. # change the name of a node. But there's nothing to change the
  83. # namespace of a node. And please: you'd better don't use renameNode.
  84. # Surprising results are lurking for the naive eye.)
  85.  

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.