2014-07-16 120 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並停止調試。調試器必須配置錯誤,但我不知道如何解決它。如果我只是運行程序沒有錯誤,它只是不會做我想要的。這就是我使用調試語句的原因。 –

相關問題