Qt XML中属性的顺序不正确

Mas*_*AKK 5 c++ xml qt qtxml

我有以下代码:

element.clear();
element.setTagName("accountpoint");
element.setAttribute("code", QString(ID_CONST)+serial);
element.setAttribute("name", QString());
element.setAttribute("serial", serial);

QFile file(filename);
file.open(QIODevice::ReadWrite);
QTextStream stream(&file);
doc.save(stream, 4);
Run Code Online (Sandbox Code Playgroud)

我以为我会得到一个XML:

<accountpoint code="4871583314750580" name="" serial="14750580">
Run Code Online (Sandbox Code Playgroud)

但是我有:

<accountpoint serial="14750580" code="4871583314750580" name="">
Run Code Online (Sandbox Code Playgroud)

为什么?

PS是的,当然,在XML文档中它并不重要,但我想获得正确的属性顺序.

MrE*_*Sir 6

我意识到这是对旧问题的部分答案,但是如果你只是希望每次有一种方法在Qt5中实现这一点时属性的顺序是一致的.

排序不一致的原因是属性存储在哈希映射中.默认情况下,每当您的应用程序开始防范某些类型的DDOS攻击时,QHash会随机化其种子.但有一个解决方法:

默认情况下启用QHash的随机化.即使程序不应该依赖于特定的QHash排序,也可能存在暂时需要确定性行为的情况,例如,用于调试或回归测试.要禁用随机化,请定义环境变量QT_HASH_SEED.该变量的内容(解释为十进制值)将用作qHash()的种子.

所以你需要做的就是设置一个名为QT_HASH_SEED的环境变量,它具有一致的值.例如,您可以在"项目"选项卡的Qt Creator中进行设置:

在Qt Creator的

这可能会或可能不会解决您的问题,但它对于单元测试来说非常方便.


Chr*_*and 6

尝试在git中存储xml设置数据时遇到了这个问题。在这种情况下(为了获得合理的差异),重要的是每次使用相同的属性顺序存储xml。该代码库已有数年历史,使用不推荐使用的Qt Xml而不是较新的QXmlStreamWriter

在这种情况下,设置QT_HASH_SEED环境变量的技巧(来自@MrEricSir的答案)效果很好。但是,也可以直接在代码中完成,例如以下示例:

qSetGlobalQHashSeed(42); // set a fixed hash value

QDomDocument doc = QDomDocument(); 
// add stuff to doc...
// ...

// save doc to file:
QFile file(filename);
QTextStream stream(&file);
stream << doc.toString(4);
file.close();

// reset hash seed with new random value.
qSetGlobalQHashSeed(-1);
Run Code Online (Sandbox Code Playgroud)

这样,您的应用程序的其余部分将像以前一样工作,从而避免遭受算法复杂性攻击


Rei*_*ica -1

XML 属性不存在“正确”顺序。标准 XML 实现不会关心它,他们也确实不关心它,而且确实如此。

人类可读性是担心属性顺序的唯一原因。如果您想编写人类可读的 XML,您可能需要编写自己的代码。

  • 然而,有一种称为[Canonical XML](http://en.wikipedia.org/wiki/Canonical_XML)的东西,其中指定了顺序并且是有原因的。您认为人类可读性是唯一原因是错误的。您是否尝试过在源代码控制系统中存储来自 QtXML 的文件并尝试比较/合并它?真是一团糟,就是这样! (12认同)