2012-03-21 31 views
6

Mam aplikacji, która buduje lewe menu, które jest oparte na składnik drzewa Qt. Aby go załadować, należy przeanalizować plik XML. Plik XML wygląda następująco:Aktualizacja pliku XML przy użyciu 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> 

Potrafię odczytać ten plik XML za pomocą 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; 

Pomiędzy parsowaniem już montuję menu. W końcu mam już wszystkie ustawione do aktualizacji XML, gdy użytkownik edytuje plik xml i przeładowuje się w aplikacji, po prostu usunę drzewo i ponownie go utworzę. Widać, że przekazuję niektóre dane na niektóre struktury, są one w zasadzie std :: vector i std :: map. Powyższy kod został napisany przykładami z dokumentacji Qt, które są całkiem przyzwoite.

Zdarza się, że napisałem prosty dialog, aby użytkownik unikał edytowania XML. Ok, dla mnie może być łatwiejsze i łatwiejsze edytowanie XML nawet z perspektywy użytkownika, ale ewentualni użytkownicy będą woleli edytować rzeczy w oknie dialogowym. Wszystko jest w porządku. Mogę pobrać dane przekazać je do aplikacji. Żaden problem.

Ale potrzebuję zaktualizować XML. Zasadniczo edycja będzie polegała na aktualizacji węzła poprzez dodanie nowego lub wstawienie węzła podrzędnego do podrzędnego. Jak zaktualizować węzeł? Czy istnieje jakiś specjalny sposób, aby to osiągnąć? Moje doświadczenia z XMLem są krótkie, zazwyczaj piszę, aktualizuję, parsuję txt i pliki binarne.

chcę zrobić coś takiego:

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(); 
    } 

Wydaje się, że przy użyciu Qt Dom jest dość przyzwoity analizowania i tworzenie plików XML, ale brakuje narzędzia do aktualizacji. Każda pomoc byłaby doceniona, nawet przykład.

Ten drugi wątek tutaj, wygląda użyteczne

Edit Value of a QDomElement?

Szukałem w internecie na przykładach, które zaktualizować plik XML. Wygląda na to, że jeśli złapię bieżący węzeł, mogę dodać do niego dziecko, do tej pory nie wiedziałem, jak to zrobić.

Dzięki za pomoc i oczywiście przepraszam za moją niewiedzę.

+1

Co to jest, że chcesz więcej niż odpowiedzi można wymienić? – Koying

+0

Witam, chcę zaktualizować węzeł. Na przykład użytkownik wpisze kategorię, polecenie i inne dane, a to wymaga aktualizacji w XML. Nie dowiedziałem się, jak wstawić nowy węzeł, ale na podstawie wcześniej istniejącego. – zlogdan

Odpowiedz

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); 

To spowoduje:

<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

Wielkie dzięki, myślę, że dałeś mi odpowiedź. – zlogdan

Powiązane problemy