2012-03-21 8 views
6

Ho un'applicazione che costruisce un menu a sinistra basato su un componente Qt dell'albero. Per caricarlo ho bisogno di analizzare un file XML. Il file XML è simile al seguente:Aggiornamento di un file XML utilizzando Qt DOM

<comandos> 
     <categoria> 
       <nome>Cupom fiscal</nome> 
       <comando> 
         <nome>01 - Abrir Cupom Fiscal</nome> 
         <env>3</env> 
         <rec>4</rec> 
         <desc>CNPJ/CPF : </desc> 
         <desc>Nome : </desc> 
         <desc>Endereco: </desc> 
       </comando> 
     </categoria> 
</comandos> 

Posso effettivamente leggere questo XML utilizzando QtDOM.

QDomDocument doc("ComandosML"); 

    QFile file("comandos.xml"); 

    int r = 0; 

    datafields.clear(); 
    receFields.clear(); 
    categories.clear(); 

    if(!file.open(QIODevice::ReadOnly)) 
     return -1; 

    if(!doc.setContent(&file)) 
    { 
     file.close(); 
     return -2; 
    } 

    // Ok we are ready to parse DOM 
    QDomElement root = doc.documentElement(); 
    if(root.tagName() != "comandos") 
     return -3; 

    QDomNode n = root.firstChild(); 
    while(!n.isNull()) 
    { 
      QDomElement e = n.toElement(); 
      if(!e.isNull()) 
      { 
      if(e.tagName() == "categoria") 
      { 
       QDomNode cat = n.firstChild(); 
       while(!cat.isNull()) 
       { 
        QDomElement CatName = cat.toElement(); 

        if (CatName.tagName() == "nome") 
        { 
         QString s = CatName.text(); 

         if (s != "") 
         { 
          categories.push_back(s); 
          item = new QStandardItem((s)); 
          item->setEditable(false); 
         } 
        } 

        if (CatName.tagName() == "comando") 
        { 

         QDomNode params = cat.firstChild(); 
         QString qdCmd; 
         int env = 0; 
         int rec = 0; 
         Categories Desc; 

         while (!params.isNull()) 
         { 
          QDomElement ParamName = params.toElement(); 

          if (ParamName.tagName() == "nome") 
          { 
           qdCmd = ParamName.text(); 
           child = new QStandardItem((qdCmd)); 
           child->setEditable(false); 
           child->setDragEnabled(false); 
           item->appendRow(child); 
          } 
          else 
          if (ParamName.tagName() == "env") 
          { 
           env = ParamName.text().toInt(); 
          } 
          else 
          if (ParamName.tagName() == "rec") 
          { 
           rec = ParamName.text().toInt(); 
          } 
          else 
          if (ParamName.tagName() == "desc") 
          { 
           Desc.push_back(ParamName.text()); 
          } 

          params = params.nextSibling(); 
         } 

         datafields.insert(pair<QString,int>( qdCmd,  env )); 
         receFields.insert(pair<QString,int>( qdCmd,  rec )); 
         descriptions.insert(pair<QString, Categories>(qdCmd, Desc)); 
        } 
        cat= cat.nextSibling(); 
       } 
       model->setItem(r++,item); 
      } 
      } 
      n = n.nextSibling(); 
    } 

    file.close(); 

    return 0; 

Tra un'analisi e l'altra ho già assemblato il menu. Dopotutto, ho già impostato tutto per l'aggiornamento dell'XML quando l'utente modifica il file xml e ricarica l'applicazione, semplicemente cancellando l'albero e ricrearlo di nuovo. Potete vedere che passo anche alcuni dati su alcune strutture, sono fondamentalmente std :: vector e std :: map. Questo codice sopra è stato scritto con esempi tratti dalla documentazione Qt, che sono abbastanza decenti a proposito.

Accade che ho scritto una semplice finestra di dialogo per impedire all'utente di modificare l'XML. Ok, per me potrebbe essere più facile e semplice modificare l'XML anche dal punto di vista dell'utente, ma i possibili utenti preferiranno modificare le cose nella finestra di dialogo. Questo è tutto OK. Posso prendere i dati per passarli all'applicazione. Nessun problema.

Ma ho bisogno di aggiornare l'XML. Fondamentalmente una modifica consisterà nell'aggiornamento del nodo aggiungendone uno nuovo o inserendo un nodo figlio in under. Come aggiorno un nodo? C'è qualche modo specifico per farlo? Le mie esperienze con XML sono brevi, di solito scrivo, aggiorno, analizzo file txt e binari.

voglio fare qualcosa di simile:

if(root.tagName() != "comandos") 
     return -3; 

    QDomNode n = root.firstChild(); 
    while(!n.isNull()) 
    { 
      QDomElement e = n.toElement(); 
      if(!e.isNull()) 
      { 
      if(e.tagName() == "categoria") 
      { 
       QDomNode cat = n.firstChild(); 
       while(!cat.isNull()) 
       { 

        QDomElement CatName = cat.toElement(); 

        if (CatName.tagName() == "nome") 
        { 
         QString s = CatName.text(); 

         if (s != qsCategory) 
         { 
          // we have not found the category 
          // add it here 

         } 
         else 
         { 
          // the category exists simply update 
         } 



        } 

        cat= cat.nextSibling(); 
       } 
      } 
      } 
      n = n.nextSibling(); 
    } 

Sembra che l'uso di Qt Dom è abbastanza decente per i file XML che creano l'analisi e, ma manca gli strumenti per gli aggiornamenti. Qualsiasi aiuto sarebbe molto apprezzato, anche un esempio.

Questo altro thread qui, sembra utile

Edit Value of a QDomElement?

ho guardato su internet per gli esempi che aggiornare un file XML. Sembra che se catturo il nodo corrente posso aggiungere un figlio, finora non ho capito come farlo.

Grazie per l'aiuto e ovviamente dispiaciuto per la mia ignoranza.

+1

Che cosa è che si desidera più di una risposta si parla? – Koying

+0

Ciao, voglio aggiornare il nodo. Ad esempio, l'utente digiterà la categoria, il comando e altri dati, e questo deve essere aggiornato nell'XML. Non ho trovato come inserire un nuovo nodo ma basato su un precedente esistente. – zlogdan

risposta

7

QDomElement newCategoriaTag = doc.createElement(QString("categoria")); 
QDomElement newNomeTag = doc.createElement(QString("nome")); 
QDomText newNomeText = doc.createTextNode(QString("Cupom fiscal 2")); 
newNomeTag.appendChild(newNomeText); 
newCategoriaTag.appendChild(newNomeTag); 
root.appendChild(newCategoriaTag); 

Questo si tradurrà in:

<comandos> 
     <categoria> 
       <nome>Cupom fiscal</nome> 
       <comando> 
         <nome>01 - Abrir Cupom Fiscal</nome> 
         <env>3</env> 
         <rec>4</rec> 
         <desc>CNPJ/CPF : </desc> 
         <desc>Nome : </desc> 
         <desc>Endereco: </desc> 
       </comando> 
     </categoria> 
     <categoria> 
       <nome>Cupom fiscal 2</nome> 
     </categoria> 
</comandos> 
+0

Molte molte grazie, penso che tu mi abbia dato la risposta. – zlogdan

Problemi correlati