From: Robert Klemme Date: 2007-02-11T21:15:08+09:00 Subject: Re: Hash into Two Arguments (for REXML) On 10.02.2007 17:48, Keith Fahlgren wrote: > Hey, > > I'm storing my XML namespaces for REXML as Hashes (for XPath.first [1]) > like so: > > RDF_NS = {"rdf" => "http://www.w3.org/1999/02/22-rdf-syntax-ns#"} > > When I need to do an XPath lookup, these work great (especially as I > can merge() more than one together), but when I have to create new > Elements and add their namespaces, the Hash isn't what's expected[2] > (it needs two distinct args). > > Is there a cooler way to get from a Hash to two args other than my > *Hash.to_a.flatten ? > > require 'rexml/document' > # => true > RDF_NS = {"rdf" => "http://www.w3.org/1999/02/22-rdf-syntax-ns#"} > # => {"rdf"=>"http://www.w3.org/1999/02/22-rdf-syntax-ns#"} > a = REXML::Element.new "rdf:RDF" > # => > a.add_namespace(*RDF_NS.to_a.flatten) > # => Here's a variant, but this is not very nice either: a.add_namespace(*RDF_NS..each {|k,v| break k,v}} > 1. namespaces: If supplied, a Hash which defines a namespace mapping: > XPath.first( node, "a/x:b", { "x"=>"http://doofus" } ) > http://www.germane-software.com/software/rexml/doc/classes/REXML/XPath.html#M000452 > > > 2. add_namespace( prefix, uri=nil ) > > Adds a namespace to this element. > prefix: the prefix string, or the namespace URI if uri is not supplied > uri: the namespace URI. May be nil, in which prefix is used as the URI > > a.add_namespace("foo", "bar") > http://www.germane-software.com/software/rexml/doc/classes/REXML/Element.html#M000490 I get the feeling that you're probably not using Hashes properly, especially since you mention you have a lot of them with one key value pair and merge them together. As far as I can see the most reasonable approach would be to have a single Hash that records all namespaces. That would be the Hash that you pass to XPath.first. When you want to add a specific namespace to an element, you would then rather do something like this: a.add_namespace("foo", namespaces["foo"]) If you want to avoid double typing you could do def namespaces.pair(key) (val = self[key]) ? [key, val] : nil end or def namespaces.pair(key) val = self[key] and [key, val] end and then a.add_namespace(*namespaces.pair("foo")) Or you reverse the logic and do def namespaces.add_ns(elem, ns) val = self[ns] and elem.add_namespace(ns, val) end Kind regards robert