6

我有以下代码:

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);

我想我会得到一个像这样的 XML:

<accountpoint code="4871583314750580" name="" serial="14750580">

但是我有:

<accountpoint serial="14750580" code="4871583314750580" name="">

为什么?

PS 是的,当然,在 XML 文档中没关系,但我想获得正确的属性顺序。

4

4 回答 4

7

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

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

qSetGlobalQHashSeed(0); // 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);

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

于 2016-10-10T07:35:45.657 回答
6

我意识到这是对一个老问题的部分回答,但如果你只是希望属性的顺序每次都保持一致,那么在 Qt5 中有一种方法可以实现这一点。

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

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

因此,您需要做的就是设置一个名为 QT_HASH_SEED 的环境变量,该变量具有一致的值。例如,您可以在 Qt Creator 的 Projects 选项卡中进行设置:

在 Qt Creator 的 Project 选项卡的 Run settings 中设置 QT_HASH_SEED 的位置

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

于 2015-05-07T04:03:50.787 回答
0

不存在 XML 属性的“正确”顺序。标准的 XML 实现不关心它,他们不关心它,这是正确的。

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

于 2014-02-03T19:56:25.833 回答
0

请使用 QXmlStreamWriter 以所需属性的确定顺序写入文件。

由于QT_HASH_SEED的设置值没有给出您尝试写入的属性的确切顺序。并且对于低于 QT5.10 的版本也无法设置 QT_HASH_SEED 的值。

最好的解决方案是 QXMLStreamWriter 下面的代码:

QString destPath = "C:/XYZ/myXLM.xml";
    QFile modelConfig(destPath);
    if (!modelConfig.open(QIODevice::WriteOnly)) {
        return 0;
    }

    QXmlStreamWriter xml(&modelConfig);
    for(int i =0;i < 10;i++)
    {
        xml.writeStartElement("ModelsSimpaConfig");
        xml.writeAttribute("Name", "NAME" + QString::number(i));
        xml.writeAttribute("ID", "ID" + QString::number(i));
        xml.writeAttribute("IDPlus", "IDPLUS" + QString::number(i));
        xml.writeAttribute("Xyz", "XYZ" + QString::number(i));
        xml.writeAttribute("Abc","ABC" + QString::number(i));

        xml.writeEndElement();
        xml.writeEndDocument();
    }


    modelConfig.close();
    qDebug() << "Writing is done";
于 2019-11-12T08:54:14.853 回答