用 Qt 中的 QDomDocument類 處理 XML 文件


XML,全稱為 可擴展標記語言”(extensible markup language).是一種非常方便的數據交換數據存儲的工具。

我們在取得一個XML格式的文件后,需要作句法分析去提取發布方提供的信息。而QtXML提供了很好的支持,包括DOM方式的實現和SAX方式的實現。

二者主要區別是:

DOM (Document Object Model) 實現方式操作非常簡單,但不適合處理過大文件;而SAX實現方式是能處理很大的XML文件,但是需要開發者寫一些復雜的代碼。Qt提供了對應於這兩種用於 讀取、操作和編寫XML的實現類,分別是QDomDocument類和QXmlStreamReader,這里我們選QDomDocument來處理XML文件。

 

首先是讀取XML

主要操作包括:

 1).讀取根節點:QDomElement  root = doc.documentElement();

2).讀取第一個子節點:QDomNode  node = root.firstChild();

3).讀取下一個子節點:node = node.nextSibling();

4).匹配結點標記:node.toElement().tagName() == "note"

5).讀取節點文本:no = childNode.toText().data();

 

     QFile file(fileName);
     
if(!file.open(QFile::ReadOnly | QFile::Text)) {
         
return false;
      }
     QString errorStr;
     
int errorLine;
     
int errorColumn;
 
      QDomDocument doc;
     
if(!doc.setContent(&file, false, &errorStr, &errorLine, &errorColumn))

{ // setContent 是將指定的內容指定給QDomDocument 解析,第一參數可以是QByteArray或者是文件名等。
         return false;
      }
 
      file.close();

 

可以通過 doc.childNodes() 獲得doc的所有的 子節點 列表QDomNodeList。比如

QDomNodeList list=doc.childNodes();

for(int i=0;i<list.count();i++)

{

QDomNode  node=list.at(i);

// qDebug()<<”node name is “<<node.nodeName();

// qDebug()<<”node type is “<<node.nodeType();

}

通過上面的方法你就能知道每個節點的 名字和類型 了,節點名字就是 標記 的名字。打印出來對照着 xml文件看就很容易明白了。QDomNode類是一個父類, QDomDocumentQDomNode的一個子類,鑒於大部分 QDomNode的類型 都是QDomDocument.那么你可以使用toDocument()函數將QDomNode類型轉換成QDomDocument.

QString text=node.toElement().text();

上面的語句可以將一個節點里的 文本 取出也就是 標記內的文本 部分。使用該函數獲得的編碼就已經是unicode格式了,不需要再做轉換。

 

 

然后是寫入XML

創建節點,將其寫入XML文件,主要操作包括:

1).創建根節點:QDomElement  root = doc.documentElement("rootName " );

2).創建元素節點:QDomElement  element = doc.createElement_x_x_x("nodeName");

3).添加 元素節點 根節點:root. a(element);

4).創建文本節點:QDomText  nodeText=doc.createTextNode("text");

5).添加 文本節點 元素節點:element. a(nodeText);

XML文件的內容:

<?xml version="1.0" encoding="UTF-8"?>

<Notes>

    <note>

        <no>001</no>

        <name>2010-05-10(13:53:24)</name>

        <content>A meeting</content>

        <font>Script MT Bold</font>

    </note>

</Notes>

     QFile  file(fileName);
     
 if(!file.open(QFile::ReadOnly | QFile::Text))
         
returnfalse;
      QString errorStr;
     
 interrorLine;
     
 interrorColumn;
      QDomDocument doc;
     
 if(!doc.setContent(&file, false, &errorStr, &errorLine, &errorColumn))
         
returnfalse;
 
      file.close();
 
      QDomElement root = doc.documentElement();
     
 if(root.tagName() != "root")
         
returnfalse;
 
      QDomElement element =   doc.createElement_x_x_x(
"file");


      QDomElement el_address = doc.createElement_x_x_x(
"address");
      QDomText text_address = doc.createTextNode(
"text");


      el_address.a
 (text_address);
      element.
a
 (el_address);
 
      QDomElement el_path = doc.createElement_x_x_x_x("path");
      QDomText text_path = doc.createTextNode(
"text");


      el_path.a (text_path);
      element.
a
 (el_path);
 
      root.
a
 (element);
 
      QFile f(fileName);
     if(!f.open(QFile::WriteOnly | QFile::Text))
         return false;
 
      QTextStream out(&f);

      out.setCodec("UTF-8"); //中文編碼

//    doc.save(out,4,QDomNode::EncodingFromTextStream);

      doc.save(out, 3);
      f.close();

這里所有需要append的字節點只能由QDomDocument對象create,而不能直接new,否則永遠也看不到新添加的節點,另外,讀取和寫入的文件流必須創建兩個,否則會將需要寫入的文檔繼續在原來文檔的后面,造成多個根節點。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM