Confusion regarding insertion of QDomElement



  • Hello all,

    I have an XML file that resembles this :
    @<?xml version='1.0' encoding='utf-8'?>
    <outputs>
    <results>
    <data />
    <data />
    <... />
    </results>
    <results>
    <data />
    <data />
    <... />
    </results>
    </outputs>
    @

    And I want to insert a new set of results:
    @
    <results>
    <data />
    <data />
    <... />
    </results>
    @

    However, regardless of how I attempt to do this using insertBefore(...) or insertAfter(...) the new QDomElement is never inserted in the correct place, i.e. inside the <outputs> element, either before or after the existing <results> elements.

    I have tried various combinations of insertBefore / After on first / lastChild and first and Last ChildElement but none of these insert the <results> in the correct position, and it always ends up outside of the <outputs> or before the xml decl!

    Can someone please help me out here. I'm beginning to think I shouldn't have got up this morning!



  • Hi,

    oit could help if you post some code that you do, the best would be to give some test program that is completly compilable...



  • Hi Gerolf,

    I have attached a working! sample as suggested, so here is the .pro file.
    @
    QT += core xml
    QT -= gui
    TARGET = xmltest
    CONFIG += console
    CONFIG -= app_bundle
    TEMPLATE = app
    SOURCES += main.cpp
    @

    and this is this source:
    @
    int main(int argc, char *argv[])
    {
    QString period("period"), xmlfile("./results.xml") ;
    QDomDocument * m_Doc = new QDomDocument() ;
    QFile * input = new QFile(xmlfile) ;
    if (input->exists())
    {
    if (input->open(QFile::ReadOnly | QFile::Text))
    {
    if (m_Doc->setContent(input))
    qDebug() << "Content Set" ;
    else
    qDebug() << "Unable set content" ;
    }
    else
    {
    qDebug() << "Unable to open file!" ;
    }
    input->close();
    }
    else
    {
    m_Doc->appendChild(m_Doc->createProcessingInstruction("xml", "version='1.0' encoding='utf-8'")) ;
    m_Doc->appendChild(m_Doc->createElement("output")) ;
    }
    QDomElement e = m_Doc->createElement("results") ;
    QStringList attribs = QStringList() << "Col_1" << "Col_2" << "Col_3" ;
    for (int row = 0; row < 4; row++)
    {
    QDomElement data = m_Doc->createElement("data") ;
    data.setAttribute(period, row + 1) ;
    for (int a = 0; a < attribs.size(); a++)
    {
    data.setAttribute(attribs.at(a), QString::number(rand(), 'f', 3)) ;
    }
    e.appendChild(data) ;
    }
    // This is the line I have a problem with.
    m_Doc->insertBefore(e, m_Doc->firstChild()) ;
    QFile outFile(xmlfile) ;
    if(outFile.open( QIODevice::WriteOnly | QIODevice::Text ))
    {
    QTextStream txtStream(&outFile;) ;
    m_Doc->save(txtStream, 4);
    }
    outFile.close();
    qDebug() << "Done." ;
    std::cin.get() ;
    }
    @

    Thanks.



  • You are only inserting after or before the root node (m_Doc) you need to get the element you want to insert before or after and then insert. This way everything should work as desired.



  • Hi KA51O this makes sense, so thank you, so I replaced line 39 with this
    @m_Doc->elementsByTagName("output").at(0).appendChild(e) ;@
    The structure of the document is now correct and survives re-runs, but I am sure this is not the correct way (in C++ code) to do this. Can anyone clarify please?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.