While trying to create shallow copies of nodes I have run into some oddities.
Firstly I have been unable to access each attribute of a node except through Xpath (as coded in each_attribute, below). This is frustrating and seems to contradict the documentation for Node.properties and Node.each_attr More strangely, my each_attribute method only works for nodes returned from a scan of the document, and not from the original nodes as added to the document. The following snippet should illustrate this: node1 = XML::Node.new('node1') node1['x'] = 'y' node1['z'] = 'a' doc.root << node1 node1.each_attribute do |name, val| # Will never reach this point! end doc.each do |node| if node.name == 'node1' node.each_attribute do |name, val| # Reaches this point for each attribute end end end There is no obvious difference between the 'node1' object, and the 'node' object yielded by doc.each. They both print the same and both yield similar looking doc objects, yet they have puzzlingly different semantics. I write in the hope that someone can explain, document and/or correct this, and if not, to ensure that this strange behaviour is at least described in this list. Here is a simple test case to illustrate the issue. require 'xml/libxml' def each_attribute(node) begin attrs = node.find('./@*') rescue TypeError # Do nothing. This error is mistakenly? raised when no matching # elements can be found return end attrs.each do |elem| yield elem.name, elem.value end end def shallowcopy(old) node = XML::Node.new(old.name) each_attribute(old) do |name, value| node[name] = value end node end doc = XML::Document.new root = XML::Node.new('root') node1 = XML::Node.new('node1') node2 = XML::Node.new('node2') node1['type'] = 'x' node2['type'] = 'y' node1['value'] = 'xval' node2['value'] = 'yval' doc.root = root root << node1 root << node2 puts "NODE1 : #{node1} :NODE1" puts "COPY OF NODE1: #{shallowcopy(node1)} :COPY OF NODE1" doc.root.each_child do |node| if node.name == 'node1' puts "NODE1 : #{node1} :NODE1" puts "COPY OF NODE1: #{shallowcopy(node)} :COPY OF NODE1" end end And this is the output generated. Note that the first copy of node1 has no attributes, while the second does. NODE1 : <node1 type="x" value="xval"/> :NODE1 COPY OF NODE1: <node1/> :COPY OF NODE1 NODE1 : <node1 type="x" value="xval"/> :NODE1 COPY OF NODE1: <node1 type="x" value="xval"/> :COPY OF NODE1 __ Marc
signature.asc
Description: This is a digitally signed message part
_______________________________________________ libxml-devel mailing list libxml-devel@rubyforge.org http://rubyforge.org/mailman/listinfo/libxml-devel