Hans de Jong Hans de Jong - 7 months ago 33
Ruby Question

How to rename node attributes

I am trying to make an XML API more friendly. Part of it is renaming names.
So far, I managed to rename the nodes to my liking, however, I can't figure out how to rename node attributes.

XML:

<result>
<rowset name="characters" key="characterID" columns="name,characterID,corporationName,corporationID,allianceID,allianceName,factionID,factionName">
<row name="Sult Dizarra" characterID="93125548" corporationName="Dry Atomic Fusion" corporationID="98012663" allianceID="154104258" allianceName="Apocalypse Now." factionID="0" factionName=""/>
<row name="Bingu Pondarra" characterID="93421113" corporationName="Realm of Echidna" corporationID="98349254" allianceID="0" allianceName="" factionID="0" factionName=""/>
<row name="Janna 'Wabisuke' Cobb" characterID="93431793" corporationName="Super Sexy" corporationID="98383185" allianceID="0" allianceName="" factionID="0" factionName=""/>
</rowset>
</result>

xml.traverse do |node|
if node.kind_of?(Nokogiri::XML::Element)
node.each do |child|
child.keys.each do |key|
key.name = rename_method(key.name)
end
end
end
end


But I went wrong somewhere here along the way. Can someone nudge me in the right direction?

Answer

Easy peasy:

require 'nokogiri'

doc = Nokogiri::XML('<root><node foo="foo" /></root>')
node = doc.at('node')
node['bar'] = node['foo']
node.delete('foo')
doc.to_xml # => "<?xml version=\"1.0\"?>\n<root>\n  <node bar=\"foo\"/>\n</root>\n"

The core of this:

node['bar'] = node['foo']
node.delete('foo')

can be simplified to:

node['bar'] = node.delete('foo')

This is all in the Nokogiri::XML::Node documentation. I'd suggest spending time reviewing it, as Node and NodeSet contain the majority of the methods used with Nokogiri.