Search code examples
c++xmlqtqdomdocument

Lastchild in xml file using QDomDocument Class


i have this xml:

<VCAAnalysis>
    <VCAStream>
        <VCAFrame width="768" height="432" rtptime=""    utctime="102157000" utctimeHigh="0" configID="0" />
        <VCAFrame width="768" height="432" rtptime="" utctime="102157160" utctimeHigh="0" configID="0">
            <Object objectID="138.96.200.59_20160126_102157160_1" minX="276" minY="0" maxX="320" maxY="123" width="44" height="123" ObjPropTag="PERSON">
            </Object>
        </VCAFrame>
        <VCAFrame width="768" height="432" rtptime="" utctime="102157320" utctimeHigh="0" configID="0" />
        <VCAFrame width="768" height="432" rtptime="" utctime="102157480" utctimeHigh="0" configID="0">
            <Object objectID="138.96.200.59_20160126_102157480_2" minX="224" minY="264" maxX="287" maxY="343" width="63" height="79" ObjPropTag="PERSON">
            </Object>
        </VCAFrame>
        <VCAFrame width="768" height="432" rtptime="" utctime="102157640" utctimeHigh="0" configID="0">
            <Object objectID="138.96.200.59_20160126_102157480_3" minX="204" minY="266" maxX="331" maxY="400" width="127" height="134" ObjPropTag="PERSON">
            </Object>
        </VCAFrame>
       <VCAFrame width="768" height="432" rtptime=""    utctime="102157000" utctimeHigh="0" configID="0" />
     </VCAStream>
  </VCAAnalysis>

I want to get the last objectID(138.96.200.59_20160126_102157480_3) in the last VCAFrame which have an object.

i tried this code but it doesn't work.

         QDomNodeList a = VCAStream.elementsByTagName("VCAFrame");

        if(a.size()!=0) {

         QDomElement lastobj = VCAStream.lastChild().toElement();
         QDomElement last = lastobj.firstChild().toElement();

         QString lastid = last.attribute("objectID");
         cout << qPrintable("laaaaaaaast "+lastid) << endl;
        }

Solution

  • This worked for me:

    QDomNodeList vcaStreams = VCAStream.elementsByTagName("VCAStream");
    QDomNodeList vcaFrames = vcaStreams.at(0).childNodes(); //Gives 6 VCAFrame tags
    QDomNodeList vcaObjects = vcaFrames.at(4).childNodes(); //Gives 1 Object tag
    qDebug() << vcaObjects.at(0).toElement().attribute("objectID"); 
    

    lastobj in your code refers to the last VCAFrame, which does not have an objectID.

    EDIT: If you need to iterate over an entire xml file. I'm assuming that you want the last vcaFrame that has an objectID in each VCAStream.

    QDomNodeList vcaStreams = VCAStream.elementsByTagName("VCAStream");
    
    for (int i = 0; i < vcaStreams.count(); ++i) {
        QDomNodeList vcaFrames = vcaStreams.at(i).childNodes(); //Gives us all VCAFrameTags
    
        //Find last tag with objectID
        QDomElement last;
        for (int j = vcaFrames.count() - 1; j >= 0; --j) {
            //Assumes there is at most one <object> tag in each VCAFrame
            if (vcaFrames.at(j).hasChildNodes()) {
                QDomElement tmp = vcaFrames.at(j).firstChild().toElement();
                if (tmp.hasAttribute("objectID")) {
                    last = tmp;
                    break;
                }
            }
        }
    
        //last now holds the last VCAFrame with an object tag or is Null
        if (last.isNull())
            qDebug() << "No objectID found";
        else 
            qDebug() << last.attribute("objectID");
    
    }
    

    I tested this on your XML file and it gave me the correct result, but I did not try adding more than one VCAStream tag.