0

我正在使用 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 始终为假,blnStartElement 始终为真。

我想要做的是在读取和处理 XML 的同时建立节点/元素层次结构。

4

1 回答 1

1

我遇到的问题是标志 blnEndElement 和 blnStartElement 在读取文件时似乎无法准确反映正确的状态,blnEndElement 始终为 false 并且 blnStartElement 始终为 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;

仅当满足条件时才执行内部代码,否则将跳过代码。

于 2016-04-12T10:51:44.683 回答