Hash into Two Arguments (for REXML)

K

Keith Fahlgren

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"
# => <rdf:RDF/>
a.add_namespace(*RDF_NS.to_a.flatten)
# => <rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'/>



Thanks,
Keith

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
 
R

Robert Klemme

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"
# => <rdf:RDF/>
a.add_namespace(*RDF_NS.to_a.flatten)
# => <rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'/>

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top