QT读取XML文件,结构

QT Reading XML file, structure

我正在使用 QXmlStreamReader 处理 XML 文件。读取循环非常简单:

    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();
    }

我正在看的XML:

    <?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>

我遇到的问题是,在读取文件时,blnEndElement 和 blnStartElement 标志似乎无法准确反映正确的状态,blnEndElement 始终为 false,而 blnStartElement 始终为 true。

我想做的是在读取和处理 XML.

的同时建立 node/element 层次结构

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.

如果我对你的问题的理解正确,你得到的局部变量 blnEndElementblnStartElement 的值是错误的。我在下面突出显示了导致此行为的 if 条件:

  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;

内部代码只在if条件满足时执行,否则跳过代码