Nokogiri::XML::Builder XML attribute ordering


Just to get it out of the way, yes, I’ve searched the lists and yes, I
well aware that attribute ordering in XML elements shouldn’t matter.
Additionally, yes, I am well aware of the Nokogiri mailing list,
Google won’t let me join the group and I can’t post without joining.
here I am.

However, my use case is slightly different. The code I am using that
ultimately writes XML files will switch the ordering of XML attributes
it generates depending on what version of Ruby is used to run the code,
what state the code is in, etc. The end result is that if I had an XML
file A with the following content at time 0:

At time > 0, where this file is regenerated either on a different
with ever so slightly modified code (but the order as defined with the
Builder is the same), the order changes. When these resulting files are
some sort of revision control, it looks like they are changing on a
basis but in reality its just the attribute ordering.

Does anyone have any tried and true solutions that enforce ordering of
attributes with Nokogiri::XML::Builder?

I have had some level of success with the following practice:

stub_xml = “”
stub_xml += “<Bar blaf=“1” what=“stuff”/>”
stub_xml += "

builder = Nokogiri::XML::Builder.with(Nokogiri::XML(stub_xml).at(“Foo”)

usual builder stuff here


This only works for really simple XML, and for XML that is deeply
the “stub” XML becomes so large that I often just end up writing the XML
generation code by hand.

Any suggestions would be appreciated! Please note that I am not tied to
Nokogiri::XML::Builder for XML building. I have heard that I can
accomplish something similar with Rexml.



While we are near the topic.
Adjacent to this issue, but in no way resolving of it:


It appears that the same problem exists with Builder. From

“The order that attributes are inserted in markup tags is undefined.”

Interestingly, though, the _special method exists, which is used by
itself to enforce the ordering of XML attributes in the XML processing
instruction typically found on the first line of an XML file. In this
case, they ensure that the order is version, encoding, standalone:

def instruct!(directive_tag=:xml, attrs={})
_ensure_no_block ::Kernel::block_given?
if directive_tag == :xml
a = { :version=>“1.0”, :encoding=>“UTF-8” }
attrs = a.merge attrs
@encoding = attrs[:encoding].downcase
“<?#{directive_tag}", "?>”,
[:version, :encoding, :standalone])