Неверный порядок атрибутов в Qt XML

c++ xml qt qtxml

1987 просмотра

4 ответа

26 Репутация автора

У меня есть следующий код:

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-документе это не имеет значения, но я хочу получить правильный порядок атрибутов.

Автор: MastAKK Источник Размещён: 03.02.2014 07:12

Ответы (4)


0 плюса

75082 Репутация автора

Не существует такого понятия, как «правильный» порядок атрибутов XML. Стандартные реализации XML не могут заботиться об этом, и они не заботятся, и это правильно.

Человеческая читаемость - единственная причина, чтобы беспокоиться о порядке атрибутов. Если вы хотите написать понятный человеку XML, вам может потребоваться развернуть собственный код.

Автор: Kuba Ober Размещён: 03.02.2014 07:56

6 плюса

6791 Репутация автора

Я понимаю, что это частичный ответ на старый вопрос, но если вы просто хотите, чтобы порядок атрибутов был согласованным каждый раз, есть способ добиться этого в Qt5.

Причина несогласованного упорядочения заключается в том, что атрибуты хранятся в хэш-карте. По умолчанию QHash рандомизирует свое начальное число каждый раз, когда ваше приложение начинает защищаться от определенных типов DDOS-атак. Но есть обходной путь :

Эта рандомизация QHash включена по умолчанию. Даже если программы никогда не должны зависеть от определенного порядка QHash, могут быть ситуации, когда вам временно необходимо детерминированное поведение, например, для отладки или регрессионного тестирования. Чтобы отключить рандомизацию, определите переменную среды QT_HASH_SEED . Содержимое этой переменной, интерпретируемое как десятичное значение, будет использовано в качестве начального числа для qHash ().

Поэтому все, что вам нужно сделать, это установить переменную среды с именем QT_HASH_SEED, которая имеет непротиворечивое значение. Например, вы можете установить это в Qt Creator на вкладке Projects:

Где установить QT_HASH_SEED в настройках Run на вкладке Project в Qt Creator

Это может или не может решить вашу проблему, но это очень удобно для модульного тестирования.

Автор: MrEricSir Размещён: 07.05.2015 04:03

6 плюса

413 Репутация автора

Я столкнулся с этой проблемой при попытке сохранить данные настроек XML в git. В этом случае (чтобы получить вменяемый diff) важно хранить 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);

Таким образом, остальная часть вашего приложения работает, как и раньше, что позволяет избежать воздействия алгоритмической сложности .

Автор: Christian Askeland Размещён: 10.10.2016 07:35

0 плюса

1 Репутация автора

Пожалуйста, используйте QXmlStreamWriter для записи файлов в определенном порядке необходимых атрибутов.

Поскольку значение параметра QT_HASH_SEED не дает точный порядок атрибутов, которые вы пытаетесь записать. а также установка значения QT_HASH_SEED невозможна для версии ниже QT5.10.

Лучшее решение - 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";
Автор: prawinrai Размещён: 12.11.2019 08:54
Вопросы из категории :
32x32