Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

how to append correctly in QT QDomElement?



  • I am generating xml file using QT DomElement. For each timestamp I want to create New QDomElement.

    At starting my vector of timestamp is empty. so In the loop first iteration after checking condition I will add QDomElement from the else part , but In next iteration if I have same timestamp then I will not create new DOM element but want to append POINTS in earlier created element and repeat. again if new timestamp come then only go to else part. but this adding in same element is not working after first iteration.

    How do I append Correctly?

    I want to get output like this,

    <Scanners>
      <TimeStamp TimeStamp="hhss1">
       <Scanner DeviceId="6001">
         <points>
         <points>
       </Scanner>
    </TimeStamp>
    <TimeStamp TimeStamp="hhss2"">
       <Scanner DeviceId="6001">
         <points>
         <points>
      </Scanner>
    </TimeStamp>
    </scanners>
    
    QDomElement scanners_element = doc.createElement("Scanners");
    root.appendChild(scanners_element);
    
    std::vector<QString> timestamp;
    
    for (size_t i = 0; i < it->second.size(); ++i) {
    
    		data::Scan scan = it->second[i];
    
    		QString temp = scan.getTimestamp().toString("hhmmss");
    
    		QDomElement time_stamp_element = doc.createElement("TimeStamp");
    		QDomElement scanner_element = doc.createElement("Scanner");
    
    		if (std::find(timestamp.begin(), timestamp.end(), temp) != timestamp.end()) {
    				//not adding node from below else
    		}
    		else {
    
    					
    			scanners_element.appendChild(time_stamp_element);
    			time_stamp_element.setAttribute("TimeStamp", temp);
    
    					
    			time_stamp_element.appendChild(scanner_element);
    			scanner_element.setAttribute("DeviceId", device_id);
    
    		}
    
    		timestamp.push_back(temp);
    
    		QDomElement points_element = doc.createElement("Points");
    
    		scanner_element.appendChild(points_element);
    
    		for (size_t j = 0; j < scan.getNumberOfPoints(); ++j) {
    			data::Scan::Point point = scan.getPoint(j);
    
    			QDomElement point_element = doc.createElement("P");
    
    			point_element.setAttribute("X", point.getX());
    			point_element.setAttribute("Z", point.getZ());
    			points_element.appendChild(point_element);
    
    		}
    }
    

  • Lifetime Qt Champion

    Hi,

    I do not see anywhere in your code something that gets the XML element matching the timestamp before adding something to it.



  • @SGaist
    here is the xml element,
    QDomElement time_stamp_element = doc.createElement("TimeStamp");

    and I am appending it to scanners element in else part of loop.
    scanners_element.appendChild(time_stamp_element);

    is this not right way? if not then then how can I access earlier created timestamp_element in else part of the loop in same code as I am generating this new xml file?


  • Lifetime Qt Champion

    Your logic should be different.

    Search for the timestamp, then search for the device and then you can add your point.

    If the timestamp is not found you can create the new nodes. If the timestamp is found but not the device, create the corresponding new nodes. Otherwise just append the points to the device you found.



  • @SGaist but the question is , if I generate one element inside if{}, how can I get same element in another iteration of for loop in else part? because in next iteration I am getting error appending to null node is not possible. or How can I remember element generated in one iteration to use later on in other iteration?

    for (size_t i = 0; i < it->second.size(); ++i) {
    if (std::find(timestamp.begin(), timestamp.end(), temp) == timestamp.end()) {
      QDomElement time_stamp_element = doc.createElement("TimeStamp");
      scanners_element.appendChild(time_stamp_element);
      time_stamp_element.setAttribute("TimeStamp", temp);
    
     timestamp.push_back(temp);
    
    QDomElement scanner_element = doc.createElement("Scanner");
    
    time_stamp_element.appendChild(scanner_element);
    scanner_element.setAttribute("DeviceId", device_id);
    
    }else{
     // here how to get same scanner_element generated in if part without creating new scanner_element
    }}
    


  • @nn26 said in how to append correctly in QT QDomElement?:

    // here how to get same scanner_element generated in if part without creating new scanner_element

    If I understand right: you want to find a QDomElement time_stamp_element which was created in a previous iteration, right? So (because that variable has gone now in the next iteration) you need to search your scanners_element children to find the existing time_stamp_element you put there which matches whatever criteria, and do your modification to that.

    Instead of just

    if (std::find(timestamp.begin(), timestamp.end(), temp) == timestamp.end()) {
    

    which simply tells you an element matching temp in not there, for the if...else you need to know where it was found if it was. So something like

    auto found = std::find(timestamp.begin(), timestamp.end(), temp);
    if (!found)
        createElementAndAppendToList(temp);
    else
        found.makeChangesToThisElement();
    

    [EDIT Having said that: I am a little lost as to what you are searching, on the one hand you are doing your find on timestamp list, on the other hand you do scanners_element.appendChild(), there seem to be 2 lists here? In some shape or form, if you want to alter an element already added into scanners_element you must find that element to update it. Since that was created via earlier:

      QDomElement time_stamp_element = doc.createElement("TimeStamp");
      scanners_element.appendChild(time_stamp_element);
      time_stamp_element.setAttribute("TimeStamp", temp);
    

    somewhere you are going to need to look though your scanners_element list, look at each of its children, look at each of those attribute "TimeStamp", find whichever one matches whatever you are searching for, and change that element.]



  • @SGaist @JonB thanks. I have to get previously generated element using QDomNodeList in next iteration and then I can append correctly for each timestamp and device.


Log in to reply