0

I am using QXmlStreamReader to process an XML file. The read loop is quite straight forward:

    if ( !file.open(QFile::ReadOnly | QFile::Text) ) {
        strErrors.append(mcszConfigFile);
        strErrors.append("\n\nDoes not exists!\n\n");
    }
    xmlrdr.setDevice(&file);
    xmlrdr.readNext();
    blnRootFound = false;
    while( !xmlrdr.atEnd() ) {
        /* [Edit] This shouldn't be here! if ( xmlrdr.isStartElement() ) */{
            QXmlStreamAttributes attrs = xmlrdr.attributes();
            QStringRef srfNodeName = xmlrdr.name();
            bool blnEndElement = xmlrdr.isEndElement();
            bool blnStartElement = xmlrdr.isStartElement();
            bool blnInvalid = true;

            if ( attrs.length() > 0 ) {
                QString strID, strNodeName = srfNodeName.toString();

                if ( attrs.hasAttribute(mcszXMLattrID) == false ) {
                    strErrors.append("Node: ");
                    strErrors.append(qPrintable(srfNodeName.toString()));
                    strErrors.append("Has no id!\n");
                    break;
                }
                strID = attrs.value(mcszXMLattrID).toString();

                if ( strNodeName.compare(mcszXMLnodeRoot) == 0 ) {
                    blnRootFound = true;
                    blnInvalid = false;
                    mstrRootID = strID;
                } else if ( strNodeName.compare(mcszXMLnodeButton) == 0
                         || strNodeName.compare(mcszXMLnodeButtonBar) == 0
                         || strNodeName.compare(mcszXMLnodeOption) == 0 ) {
                    blnInvalid = false;
                } else if ( strNodeName.compare(mcszXMLnodeControl) == 0 ) {
                    for( int t=0; mcpszValidControlTypes[t]!=NULL; t++ ) {
                        if ( strID.compare(mcpszValidControlTypes[t]) == 0 ) {
                            blnInvalid = false;
                            break;
                        }
                    }
                }
                if ( strID.length() > 0 && blnInvalid == false ) {
                    clsXMLnode objNode = clsXMLnode(strNodeName, &attrs, this);                    
                    msmapNodes.insert(std::pair<QString, clsXMLnode>(strID, objNode));
                    msmapAreas.insert(std::pair<QString, QRect>(strID, objNode.rctGetGeom()));
                    if ( blnStartElement == true ) {

                    }
                }
            }
        }
        xmlrdr.readNext();
    }
    if ( file.isOpen()  ) {
        file.close();
    }

The XML that I am reading:

    <?xml version="1.0" encoding="utf-8"?>
    <!--
     Node:          gui
     Attrbuttes:    left, right, top and bottom defines the pixel white space to allow
                    from the edge of the display
            language, should be set to the appropriate country code, an XML file named using
            the country code must exist, e.g. 44.xml
    //-->
    <gui id="root" bottom="0" left="0" right="0" top="24" language="44">
      <control id="trainstrip"
           x="(center:SCREEN) - (25%:SCREEN_WIDTH)" y="(top:SCREEN)" height="40px" width="(50%:SCREEN_WIDTH)"/>
      <control id="elevationstrip"
               x="(left:trainstrip) - 56px" y="(top:trainstrip) + (height:trainstrip) + 24px" width="56px" height="{75%:SCREEN_HEIGHT}"/>
      <control id="lofmimics"
           color_arc="#ffaaaaaa"
               color_axis="#fff0000"
               color_bg="#ffaaaaaa"
               color_needle="#ffffff00"
               color_min_limit="#ffbbbb00"
               color_max_limit="#ffcc00cc"
               color_port="#ff00aa00"
               color_starboard="'#ffaa0000"
               elevation_height="275px"
           elevation_mech_max="85"
               elevation_mech_min="-10"
               elevation_max="85"
               elevation_margin_left="64px"
               elevation_margin_bottom="64px"
               elevation_min="-10"
               elevation_pensize_limit="3"
               elevation_pensize_reading="3"
               elevation_width="[elevation_height]"
               elevation_x="0px"
           elevation_y="0px"
               training_mech_starboard="170"
               training_mech_port="-170"
               training_pensize_port="5"
               training_pensize_starboard="5"
               training_pensize_limit="3"
               training_pensize_reading="3"
               training_starboard="150"
               training_port="-150"
               training_width="(left:elevationstrip)"
               training_height="([training_width])"
           training_x="([elevation_x])"
           training_y="([elevation_height])"
               x="(left:SCREEN)"
           width="([x]:elevationstrip)"
           height="([training_height]) + ([elevation_height])"
               y="(bottom:SCREEN) - ([height])"/>
      <buttonbar id="modes"      
             height="50%"
             width="100px"
             x="(RIGHT:SCREEN) - ([width])"
             y="(TOP:SCREEN)"
             title="MODE"
             color_bg="#ffaaaaaa"
             border="inset:#ffcccccc,#ff333333"
             button_height="24px"
                 button_width="80px"
             vertical_space="4px">
        <button id="btnsetup" color_bg="#ff3399ff" x="0px" y="{top:modes}">
          <option value="0" text="operate<"/>
          <option value="1" text="setup"/>
          <option value="2" text="install"/>
          <option value="3" text="startup"/>
          <option value="4" text="shutdown"/>
        </button>     
      </buttonbar>
    </gui>

The issue I'm having is that the flags blnEndElement and blnStartElement do not appear to accurately reflect the correct states when reading the file, blnEndElement is always false and blnStartElement is always true.

What I want to do is build up the node/element hierarchy whilst reading and processing the XML.

2
  • that is because, after main while loop, you have the if condition if ( xmlrdr.isStartElement() ). Commented Apr 12, 2016 at 10:11
  • @vcp, Please explain. I've checked the values in the debugger and the flag for blnStartElement is always true. Commented Apr 12, 2016 at 10:12

1 Answer 1

1

The issue I'm having is that the flags blnEndElement and blnStartElement do not appear to accurately reflect the correct states when reading the file, blnEndElement is always false and blnStartElement is always true.

If I understand your issue correctly, you are getting wrong values for local variables blnEndElement and blnStartElement. I highlight below the if condition which is the cause for this behavior:

  while( !xmlrdr.atEnd() ) {
        if ( xmlrdr.isStartElement() ) {
        //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            QXmlStreamAttributes attrs = xmlrdr.attributes();
            QStringRef srfNodeName = xmlrdr.name();
            bool blnEndElement = xmlrdr.isEndElement();  
            bool blnStartElement = xmlrdr.isStartElement(); 
            //   ^^^^^^^^^^ Same as above if condition, ALWAYS be TRUE, if control reaches this line.

            bool blnInvalid = true;

The internal code is executed only when if condition is satisfied else code will be skipped.

Sign up to request clarification or add additional context in comments.

1 Comment

Doh, I see exactly what you mean, I'm missed this completely, thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.