Incorrect order of attributes in Qt XML

后端 未结 4 575
迷失自我
迷失自我 2021-01-18 15:18

I have the following code:

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


        
相关标签:
4条回答
  • 2021-01-18 15:53

    I realize this is a partial answer to an old question, but if you just want the order of the attributes to be consistent every time there's a way to achieve this in Qt5.

    The reason for the inconsistent ordering is that the attributes are stored in a hash map. By default QHash randomizes its seed every time your application starts to guard against certain types of DDOS attacks. But there is a workaround:

    This randomization of QHash is enabled by default. Even though programs should never depend on a particular QHash ordering, there may be situations where you temporarily need deterministic behavior, e.g. for debugging or regression testing. To disable the randomization, define the environment variable QT_HASH_SEED. The contents of that variable, interpreted as a decimal value, will be used as the seed for qHash().

    So all you need to do is set an environment variable named QT_HASH_SEED that has a consistent value. For example you can set this in Qt Creator in the Projects tab:

    Where to set QT_HASH_SEED in the Run settings in the Project tab in Qt Creator

    This may or may not solve your problem, but it's super handy for unit testing.

    0 讨论(0)
  • 2021-01-18 15:56

    There is no such thing as a "right" order of XML attributes. Standard XML implementations can't care about it, and they don't, and rightly so.

    Human readability is about the only reason to worry about attribute order. If you want to write human-readable XML, you may need to roll your own code.

    0 讨论(0)
  • 2021-01-18 16:07

    Please use QXmlStreamWriter to write files in the deterministic order of attributes needed.

    As the setting value of QT_HASH_SEED does not give exact order of attributes you trying to write. and Also setting the value of QT_HASH_SEED is not possible for the Below QT5.10 version.

    Best Solution is QXMLStreamWriter below code:

    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";
    
    0 讨论(0)
  • 2021-01-18 16:14

    I ran into this issue when trying to store xml setting data in git. In this case (in order to get a sane diff) it is important to store the xml using the same attribute ordering each time. The code base was several years old, using the deprecated Qt Xml instead of the newer QXmlStreamWriter.

    The trick of setting the QT_HASH_SEED environment variable (from @MrEricSir's answer) works well in this case. However, it can also be done directly in code, like in this example:

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

    This way, the rest of your application works as before, thus avoiding exposure to algorithmic complexity attacks.

    0 讨论(0)
提交回复
热议问题