Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Store the QDocument attributes in an ordered way
Qt 6.11 is out! See what's new in the release blog

Store the QDocument attributes in an ordered way

Scheduled Pinned Locked Moved Unsolved General and Desktop
3 Posts 3 Posters 1.6k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Offline
    L Offline
    Lolo67
    wrote on last edited by
    #1

    I am using the following function to write the content from a QDomDocument into a file.

    int MyClass::writeFile(const QString outfile,const QDomDocument* XMLContent)
    {
        QFile out(outfile);
        if (out.open(QIODevice::ReadWrite|QIODevice::Truncate))
        {
            LOG(INFO) << "Write Out File: " << outfile.toStdString();
            QTextStream stream( &out );
            QString Result_string;
            int ident = 3;
            Result_string = XMLContent->toString(ident);
            stream << Result_string << endl;
            out.close();
            return -1;
        }
        else
        {
            LOG(ERROR) << "ERROR - Cannot write file: " << outfile.toStdString();
            return 0;
        }
    }
    

    I am observing that the produced file does not always have the arguments put in the same order within a node.

    F.e. sometimes it might be:

    <myObject Attribute1="111" Attribute2="222" Attribute3="333">
    ...
    </myObject>
    

    and sometimes it might be:

    <myObject Attribute3="333" Attribute1="111" Attribute2="222">
    ...
    </myObject>
    

    I understand that this has no consequence on the generated XML - However it would be convenient if the attributes would always be stored in the same order so that I would able to easily diff two consecutively generated files.

    m.sueM 1 Reply Last reply
    0
    • L Lolo67

      I am using the following function to write the content from a QDomDocument into a file.

      int MyClass::writeFile(const QString outfile,const QDomDocument* XMLContent)
      {
          QFile out(outfile);
          if (out.open(QIODevice::ReadWrite|QIODevice::Truncate))
          {
              LOG(INFO) << "Write Out File: " << outfile.toStdString();
              QTextStream stream( &out );
              QString Result_string;
              int ident = 3;
              Result_string = XMLContent->toString(ident);
              stream << Result_string << endl;
              out.close();
              return -1;
          }
          else
          {
              LOG(ERROR) << "ERROR - Cannot write file: " << outfile.toStdString();
              return 0;
          }
      }
      

      I am observing that the produced file does not always have the arguments put in the same order within a node.

      F.e. sometimes it might be:

      <myObject Attribute1="111" Attribute2="222" Attribute3="333">
      ...
      </myObject>
      

      and sometimes it might be:

      <myObject Attribute3="333" Attribute1="111" Attribute2="222">
      ...
      </myObject>
      

      I understand that this has no consequence on the generated XML - However it would be convenient if the attributes would always be stored in the same order so that I would able to easily diff two consecutively generated files.

      m.sueM Offline
      m.sueM Offline
      m.sue
      wrote on last edited by
      #2

      Hi @Lolo67

      There is an old bug report which shows a workaround: https://bugreports.qt.io/browse/QTBUG-8158

      -Michael.

      1 Reply Last reply
      1
      • LabanKL Offline
        LabanKL Offline
        LabanK
        wrote on last edited by
        #3

        Make use of QStreamWriter instead, that solved this issue for me!

        QDomElement element = getUserDomElement();
        
        QByteArray byte_array;
        QXmlStreamWriter stream(&byte_array);
        
        stream.writeStartDocument();
        
        //(Recursive part)
        stream.writeStartElement(element.tagName());
        
        QVector<QString> attribute_names;
        const QDomNamedNodeMap attributes = element.attributes();
        for(quint32 i = 0; i < attributes.length(); ++i) {
          attribute_names << attributes.item(i).toAttr().name();
        }
        
        std::stable_sort(attribute_names.begin(), attribute_names.end());
        
        foreach(QString attr_name, attribute_names) {
          QDomAttr attr = attributes.namedItem(attr_name).toAttr();
          stream.writeAttribute(attr.name(), attr.value());
        }
        
        //If has children call recursive function...
        
        stream.writeEndElement();
        //(End recursive part)
        
        stream.writeEndDocument();
        
        QFile file("ordered_attributes.xml");
        if(file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) {
          file.write(byte_array);
          file.flush();
          file.close();
        }
        

        This will write one QDomElement on format:

        <tag a="value_a" b="value_b" ...></tag>
        

        where attributes are ordered by choice of sorting algorithm.

        If QDomElement has children this procedure can be called recursively with stream as argument.

        1 Reply Last reply
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved