传递QXmlStreamReader实例到类
Pass QXmlStreamReader Instance to Class
我正在尝试使用QXmlStreamReader读取XML文档。当我试图将指针传递给阅读器到其他类时,我遇到了问题。我在一个类中创建了阅读器的实例。该类读取XML,直到遇到定义新类的块。我创建了新类的一个实例,然后调用该类中的一个函数来继续读取特定于它的XML。例如:
void SF_UnitClass::ReadModes()
{
Q_ASSERT(XML.isStartElement() && XML.name() == MODES);
NumModes = XML.attributes().value(COUNT).toInt();
while (XML.readNextStartElement())
{
if (XML.name() == MODE)
{
ModeClass* pMode = new ModeClass(this);
ModeList += XML.attributes().value(ID).toString();
pMode->ReadXML(&XML);
{
}
}
else
{
XML.raiseError(QObject::tr("Something other than Mode block encountered in Modes block"));
}
}
}
void ModeClass::ReadXML(QXmlStreamReader* pXML)
{
Q_ASSERT(pXML->isStartElement() && pXML->name() == MODE);
while (pXML->readNextStartElement())
{
int nameIndex = ModeList.indexOf(pXML->name().toString());
if(nameIndex != -1)
{
switch(nameIndex)
{
case 0:
{
qDebug() << "Mode: Receivers";
NumReceivers = pXML->readElementText().toInt();
break;
}
case 1:
{
qDebug() << "Mode: Channels";
ReadChannels(pXML);
break;
}
case 2:
{
qDebug() << "Mode: Servos";
ReadServos(pXML);
break;
}
}
}
else
{
qDebug() << "Mode: Error " << name;
pXML->raiseError(QObject::tr("Unrecognized keyword for Mode"));
}
}
}
void ModeClass::ReadChannels(QXmlStreamReader* pXML)
{
Q_ASSERT(pXML->isStartElement() && pXML->name() == CHANNELS);
NumChannels = pXML->attributes().value(COUNT).toInt();
while (pXML->readNextStartElement())
{
if (pXML->name() == CHANNEL)
{
qDebug() << "Mode: Read Channel";
ChannelClass* pChannel = new ChannelClass(this);
pChannel->ReadXML(pXML);
}
else
{
pXML->raiseError(QObject::tr("Something other than Channel block enc
}
}
}
void ModeClass::ReadServos(QXmlStreamReader* pXML)
{
Q_ASSERT(pXML->isStartElement() && pXML->name() == SERVOS);
NumServos = pXML->attributes().value(COUNT).toInt();
while (pXML->readNextStartElement())
{
if (pXML->name() == SERVO)
{
qDebug() << "Mode: Read Servo";
ServoClass* pServo = new ServoClass(this);
pServo->ReadXML(pXML);
}
else
{
qDebug() << "Servos: raiseError";
pXML->raiseError(QObject::tr("Something other than Servo block encou
}
}
qDebug() << "Mode: Read Servos Exit";
}
void ChannelClass::ReadXML(QXmlStreamReader* pXML)
{
Q_ASSERT(pXML->isStartElement() && pXML->name() == CHANNEL);
ChannelNumber = pXML->attributes().value(ID).toInt();
while (pXML->readNextStartElement())
{
int nameIndex = ChannelList.indexOf(pXML->name().toString());
if(nameIndex != -1)
{
switch(nameIndex)
{
case 0:
{
UserName = pXML->readElementText();
break;
}
case 1:
{
EndPointHold = String2Bool(pXML->readElementText());
break;
}
case 2:
{
ServoPriority = String2Bool(pXML->readElementText());
break;
}
}
}
else
{
pXML->raiseError(QObject::tr("Unrecognized keyword for Channel"));
}
}
}
void ServoClass::ReadXML(QXmlStreamReader* pXML)
{
Q_ASSERT(pXML->isStartElement() && pXML->name() == SERVO);
ServoNumber = pXML->attributes().value(ID).toInt();
while (pXML->readNextStartElement())
{
int nameIndex = ServoList.indexOf(pXML->name().toString());
qDebug() << "Servo: NameIndex: " << nameIndex;
if(nameIndex != -1)
{
switch(nameIndex)
{
case 0:
{
Offset = pXML->readElementText().toInt();
break;
}
case 1:
{
PosFactor = pXML->readElementText().toInt();
break;
}
case 2:
{
NegFactor = pXML->readElementText().toInt();
break;
}
case 3:
{
SecServo = pXML->readElementText().toInt();
break;
}
case 4:
{
Unit = pXML->readElementText().toInt();
break;
}
case 5:
{
Ser1 = pXML->readElementText().toInt();
break;
}
case 6:
{
Ser2 = pXML->readElementText().toInt();
break;
}
case 7:
{
Ser3 = pXML->readElementText().toInt();
break;
}
}
}
else
{
qDebug() << "Servo: raiseError";
pXML->raiseError(QObject::tr("Unrecognized keyword for Servo block")
}
}
qDebug() << "Servo: Exit ";
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml>
<SmartFlyUnit version="1.0">
<UnitName>PowerExpander Eq10E</UnitName>
<UnitCode>PE-5</UnitCode>
<UnitID>1</UnitID>
<MinRev>1.0</MinRev>
<MaxRev>1.9</MaxRev>
<Servos>36</Servos>
<Outputs>32</Outputs>
<UnitMode>Chan</UnitMode>
<Modes Count="2">
<Mode ID="Chan">
<Receivers>1</Receivers>
<Channels Count="10">
<Channel ID="0">
<UserName></UserName>
<EndPtHold>Off</EndPtHold>
<ServoPri>Off</ServoPri>
</Channel>
<Channel ID="1">
<UserName></UserName>
<EndPtHold>Off</EndPtHold>
<ServoPri>Off</ServoPri>
</Channel>
</Channels>
<Servos Count="36">
<Servo ID="0">
<Offset>0</Offset>
<PosFact>1.0000</PosFact>
<NegFact>1.0000</NegFact>
<Reverse>Off</Reverse>
<SecServo>0xFF</SecServo>
<Unit>0xFF</Unit>
<Ser1>0xFF</Ser1>
<Ser2>0xFF</Ser2>
<Ser3>0xFF</Ser3>
</Servo>
<Servo ID="1">
<Offset>0</Offset>
<PosFact>1.0000</PosFact>
<NegFact>1.0000</NegFact>
<Reverse>Off</Reverse>
<SecServo>0xFF</SecServo>
<Unit>0xFF</Unit>
<Ser1>0xFF</Ser1>
<Ser2>0xFF</Ser2>
<Ser3>0xFF</Ser3>
</Servo>
</Servos>
</Mode>
</Modes>
<MCUs Count="1">
<MCU ID="0">
<FileName>/PE-5/PE-5_M0_1_00.sffw</FileName>
</MCU>
</MCUs>
<FPGAs Count="1">
<FPGA ID="0">
<Configs Count="2">
<Config ID="0">
<FileName>/PE-5/PE-5_F0C0_1_00.sffw</FileName>
</Config>
<Config ID="1">
<FileName>/PE-5/PE-5_F0C1_1_00.sffw</FileName>
</Config>
</Configs>
</FPGA>
</FPGAs>
</SmartFlyUnit>
我添加了ModeClass用来识别通道和伺服块的代码。我还添加了ChannelClass和ServoClass的代码。最后,我添加了XML文件的编辑版本,但足以显示问题。这个XML可以很好地读取我的TreeWidget代码(未显示)。当我把它读到上面的代码中时发生的事情是,所有的通道都被正确读取,然后它读取第一个伺服块并一直返回到主ModeClass循环,而不是读取ModeClass::ReadServos中的下一个伺服。我知道这是很多代码,但它似乎是唯一的方式来显示问题。谢谢你, Qt文档说:
读取当前元素中的下一个开始元素。返回到达开始元素时为True。当结束元素是到达,或者发生错误时,返回false。
所以当你遇到start element时,使用readNextStartElement()
将在你找到的
。
<xml>
</xml>
<xml>
</xml>
将会发生什么:
-
readNextStartElement()
将在第一个<xml>
节点停止 -
readNextStartElement()
将返回false,因为它发现</xml>
在稍作修改的例子中:
<xml>
<child>
</child>
</xml>
<xml>
</xml>
-
readNextStartElement()
将在第一个<xml>
节点上停止 -
readNextStartElement()
将在<child>
节点停止 -
readNextStartElement()
将返回false,因为<child>
节点中没有xml节点
你会问,你应该怎么做?
当你找到你感兴趣的节点,并阅读你需要的所有信息后,你必须调用skipCurrentElement()
,这样QXmlStreamReader
将转到当前元素的末尾
修改一下第一个例子:
<xml>
</xml>
<xml>
</xml>
-
readNextStartElement()
将在第一个<xml>
节点上停止 -
skipCurrentElement()
将在第一个<xml>
节点关闭时停止 -
readNextStartElement()
将在第二个<xml>
节点上停止
相关文章:
- 从C++实例化QML
- 在全局变量中保存类的实例以重新创建类(创建"backup")
- OpenGL - 在抛出"__gnu_cxx::recursive_init_error"实例后终止调用?
- 如何在c++中为模板函数实例创建快捷方式
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 设计一个只能由特定类实例化的类(如果可能的话,通过make_unique)
- 如何创建一个空的全局类并在启动时实例化它
- 无法创建抽象类的实例
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 我收到以下错误:抛出'std::bad_alloc'实例后终止调用
- 建议在运行时将带有类实例的列表从c++导入qml
- 约束和显式模板实例化
- 通过实例理解std::move及其目的
- 为什么包含windows.h会产生语法错误,从而阻止类的实例化?(C2146,C2065)
- 有没有一种"cleaner"的方法可以在指向基的指针向量中找到派生类的第一个实例?
- 正在生成未知类实例
- 从DLL中删除类的实例
- 在std::vector上存储带有模板的类实例
- 为什么创建友元类的实例会导致"undefined reference to"错误?