2014-07-16 91 views
1

我正在尝试使用QXmlStreamReader读取XML文档。当我尝试将指向读者的指针传递给其他类时,我遇到了问题。我在一个课堂上创建了一个读者实例。该类读取XML直到定义一个新类的块。我创建并实例化新类,然后调用该类中的函数以继续读取特定于其的XML。例如:将QXmlStreamReader实例传递给类

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中的下一个伺服器。我知道这是很多代码,但它似乎是展示该问题的唯一方法。谢谢,

+0

你需要发布pMode-> ReadXML的 –

+0

的身体OK,增加了更多的代码,我读XML很多。 –

回答

0

Qt的文档说:

读取,直到当前元素中的下一个开始元素。返回 在达到开始元素时为true。当达到末尾元素 或发生错误时,返回false。

因此当你遇到开始元素,使用readNextStartElement()会在元素中搜索您发现

<xml> 
</xml> 
<xml> 
</xml> 

什么会发生在这里:

  1. readNextStartElement()将首先停止<xml>节点
  2. readNextStartElement()将返回false,因为它在一点点变形例发现</xml>

<xml> 
    <child> 
    </child> 
</xml> 
<xml> 
</xml> 
  1. readNextStartElement()将停止第一<xml>节点上
  2. readNextStartElement()将停止<child>节点上
  3. readNextStartElement()将返回false,因为0123内没有xml节点节点

你应该怎么做,你问?

后,你到节点你insterest中,读你需要,你必须调用的所有信息skipCurrentElement()所以QXmlStreamReader会去当前元素结束

所以modyfing一点点的第一个样本:

<xml> 
</xml> 
<xml> 
</xml> 
  1. readNextStartElement()将停止第一<xml>节点上
  2. skipCurrentElement()将停在第一<xml>点头的开闭Ë
  3. readNextStartElement()将停止第二<xml>节点
+0

我看到你在说什么,但我正在阅读整个文件并应该识别所有节点。我不想跳过。我正在从XML构建数据库。我发布了更多的代码和一个简短的XML文件。一个更好的描述什么有效,没有被添加,我希望。谢谢。 –

+0

当然,你不想跳过任何东西。您是否尝试使用调试器来查看解析代码的确切位置?在'SF_UnitClass :: ReadModes()'中设置断点并且一步一步 –

+0

由于某种原因,我在调试器时遇到了问题。我设置了一个断点,当我到达那里时,如果我做了一步,它给我一个错误,说它不能插入断点-422并停止调试。调试器必须配置错误,但我不知道如何解决它。如果我只是运行程序没有错误,它只是不会做我想要的。这就是我使用调试语句的原因。 –

相关问题