Bug report #21375

Order of attributes in QGS XML is non-stable

Added by Adam Liddell over 5 years ago. Updated over 5 years ago.

Status:Open
Priority:Normal
Assignee:-
Category:Project Loading/Saving
Affected QGIS version:3.6.0 Regression?:No
Operating System:Windows 7 Easy fix?:No
Pull Request or Patch supplied:No Resolution:
Crashes QGIS or corrupts data:No Copied to github as #:29192

Description

When saving a project, the order of the attributes on the XML elements in the saved QGS file appears to be non-stable. When trying to version control a project, this causes massive diff 'noise' from attributes being reordered, even when the actual data in the attributes is identical.

For example, on one save, an element may be written as:
<layer-tree-layer source="?query=SELECT..." id="some_layer" providerKey="virtual" expanded="1" name=some_layer" checked="Qt::Unchecked">

The next time the file is saved, the order of the attrbutes may change for the same element:
<layer-tree-layer providerKey="virtual" expanded="1" id="some_layer" name="some_layer" source="?query=SELECT..." checked="Qt::Unchecked">

Simply resaving a file immediately after a previous save does not appear to trigger this, so there is some 'change' in the project that causes the attributes to reorder.
As a proposed solution, the attributes on the elements should be ordered stably, perhaps alphabetically?

The order of the XML elements within the document appears to be stable.

Tested in 3.4.4 and 3.6.0.

History

#1 Updated by Alessandro Pasotti over 5 years ago

IMO this is a won't fix, the attribute order is random due to QT internal implementation https://doc.qt.io/qt-5/qhash.html#algorithmic-complexity-attacks

You can control with an env var as explained in the docs.

#2 Updated by Adam Liddell over 5 years ago

Ok, I see the issue with using QDomDocument in QT5 to get stable ordering. However, whilst using QT_HASH_SEED would work on one machine, the output is supposedly not necessarily stable across different machines or versions even when set to 0, which doesn't solve the (perhaps minor) problem of using shared version control on a project.

Would there be benefit to post-processing the generated XML into canonical form (https://en.wikipedia.org/wiki/Canonical_XML), as suggested here: https://geidav.wordpress.com/2013/02/27/deterministic-attribute-order-in-xml-documents-in-qt-5/? Perhaps as an option if you don't want to pay the price for every project.

Also available in: Atom PDF