我正在使用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的同时建立节点/元素层次结构。
答案 0 :(得分:1)
我遇到的问题是标志blnEndElement和blnStartElement在读取文件时似乎没有准确反映正确的状态,blnEndElement始终为false且blnStartElement始终为true。
如果我正确理解了您的问题,您会收到错误的局部变量值blnEndElement
和blnStartElement
。我在下面突出显示了导致此行为的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;
仅当条件满足时才执行内部代码,否则将跳过代码。