Forum: Ruby Hash into Two Arguments (for REXML)

Announcement (2017-05-07): is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see and for other Rails- und Ruby-related community platforms.
B7d00e6bd04c81d1fd78554a3d0c38b7?d=identicon&s=25 Keith Fahlgren (Guest)
on 2007-02-10 17:49
(Received via mailing list)

I'm storing my XML namespaces for REXML as Hashes (for XPath.first [1])
like so:

 RDF_NS = {"rdf" => ""}

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" => ""}
# => {"rdf"=>""}
a = "rdf:RDF"
# => <rdf:RDF/>
# => <rdf:RDF xmlns:rdf=''/>


1. namespaces:  If supplied, a Hash which defines a namespace mapping:
 XPath.first( node, "a/x:b", { "x"=>"http://doofus" } )

2.   add_namespace( prefix, uri=nil )

Adds a namespace to this element.
  prefix:  the prefix string, or the namespace URI if uri is not
  uri:  the namespace URI. May be nil, in which prefix is used as the

  a.add_namespace("foo", "bar")
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2007-02-11 13:16
(Received via mailing list)
On 10.02.2007 17:48, Keith Fahlgren wrote:
> (it needs two distinct args).
> a.add_namespace(*RDF_NS.to_a.flatten)
> # => <rdf:RDF xmlns:rdf=''/>

Here's a variant, but this is not very nice either:

a.add_namespace(*RDF_NS..each {|k,v| break k,v}}

>  a.add_namespace("foo", "bar")

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


def namespaces.pair(key)
   val = self[key] and [key, val]

and then


Or you reverse the logic and do

def namespaces.add_ns(elem, ns)
   val = self[ns] and elem.add_namespace(ns, val)

Kind regards

This topic is locked and can not be replied to.