Qt中對XML的處理方式

來源:互聯網
上載者:User

標籤:des   blog   http   os   io   使用   strong   ar   for   

XML(eXtensible Markup Language,可延伸標記語言 (XML))是普通用於資料交換和資料存放區的一種多用途文字檔格式;

SVG(可標量向量圖形)XML格式,QtSvg模組提供了可用於載入並呈現SVG映像的類;

MathML(數學標記語言)XML格式的繪製文檔,可以使用Qt Solution中的QtMmlWidget操作;

 

對於一般的XML資料處理,Qt提供了QtXml模組,QtXml提供了三種不同的應用程式介面來讀取XML文檔:

1、QXmlStreamReader

     用於讀取格式良好的XML文檔的快速解析器,該類最快且最便於使用,並提供了與其他Qt相容的API,很適用於編寫單通道解析器;

     是QXmlStreamReader的記號:

      

   如下XML文檔:

         <body>

                 <quoto>My test XML</quoto>

        </body>

QXmlStreamReader解析這個文檔,readNext()每次讀取一個元素都會產生一個新記號,用getter函數可以讀取更多資訊:

       遍曆整個文檔會有如下輸出:

     StartDocument

    StartElement(name()=="body")

       StartElement(name()=="quoto")

   Characters(text()=="My test XML")

   EndElement(name()=="quoto")

   EndElement(name()=="body")

 

QXmlStreamReader讀取如下的XML檔案

<?xml version="1.0"?>
<bookindex>
    <entry term="sidebearings">
        <page>10</page>
        <page>34-35</page>
        <page>307-308</page>
    </entry>
    <entry term="subtraction">
        <entry term="of pictures">
            <page>115</page>
            <page>244</page>
        </entry>
        <entry term="of vectors">
            <page>9</page>
        </entry>
    </entry>
</bookindex>


通常是按層遍曆方式,下面來從代碼體驗一下:

XmlStreamReader::XmlStreamReader(QTreeWidget*tree)

{
    treeWidget = tree;
}
bool XmlStreamReader::readFile(const QString &fileName)
{
    QFile file(fileName);
    if (!file.open(QFile::ReadOnly | QFile::Text)) {
        std::cerr << "Error: Cannot read file " << qPrintable(fileName)
                  << ": " << qPrintable(file.errorString())
                  << std::endl;
        return false;
    }
    qDebug()<<QString("read success");
    reader.setDevice(&file);
    reader.readNext();
    while (!reader.atEnd()) {
        if (reader.isStartElement()) {
            if (reader.name() == "bookindex") {
                readBookindexElement();
            } else {
                reader.raiseError(QObject::tr("Not a bookindex file"));
            }
        } else {
            reader.readNext();
        }
    }
    file.close();
    if (reader.hasError()) {
        std::cerr << "Error: Failed to parse file "
                  << qPrintable(fileName) << ": "
                  << qPrintable(reader.errorString()) << std::endl;
        return false;
    } else if (file.error() != QFile::NoError) {
        std::cerr << "Error: Cannot read file " << qPrintable(fileName)
                  << ": " << qPrintable(file.errorString())
                  << std::endl;
        return false;
    }
    return true;
}
void XmlStreamReader::readBookindexElement()
{
    reader.readNext();
    while (!reader.atEnd()) {
        if (reader.isEndElement()) {
            reader.readNext();
            break;
        }
        if (reader.isStartElement()) {
            if (reader.name() == "entry") {
                readEntryElement(treeWidget->invisibleRootItem());
            } else {
                skipUnknownElement();
            }
        } else {
            reader.readNext();
        }
    }
}
void XmlStreamReader::readEntryElement(QTreeWidgetItem *parent)
{
    QTreeWidgetItem *item = new QTreeWidgetItem(parent);
    item->setText(0, reader.attributes().value("term").toString());
    reader.readNext();
    while (!reader.atEnd()) {
        if (reader.isEndElement()) {
            reader.readNext();
            break;
        }
        if (reader.isStartElement()) {
            if (reader.name() == "entry") {
                readEntryElement(item);
            } else if (reader.name() == "page") {
                readPageElement(item);
            } else {
                skipUnknownElement();
            }
        } else {
            reader.readNext();
        }
    }
}
void XmlStreamReader::readPageElement(QTreeWidgetItem *parent)
{
    QString page = reader.readElementText();
    if (reader.isEndElement())
        reader.readNext();
    QString allPages = parent->text(1);
    if (!allPages.isEmpty())
        allPages += ", ";
    allPages += page;
    parent->setText(1, allPages);
}
void XmlStreamReader::skipUnknownElement()
{
    reader.readNext();
    while (!reader.atEnd()) {
        if (reader.isEndElement()) {
            reader.readNext();
            break;
        }
        if (reader.isStartElement()) {
            skipUnknownElement();
        } else {
            reader.readNext();
        }
    }
}

 

 

2、DOM(文件物件模型)

   把XML文檔轉換為應用程式可以遍曆的樹形結構,主要優點是它能以任意順序遍曆XML文檔的樹形表示,同時可以用於多通道解析演算法;

      有一些應用程式甚至使用DOM樹作為它們的基本資料結構。

       Qt提供了一套用於讀取/操作和編寫XML檔案的非驗證型二級DOM實現——這裡沒有明白非驗證型二級的概念,,,,

     為DOM節點間的父子關係圖:

Qt中Dom的處理函數,一般只是在函數名前加QDom,常用的 QDomNode, QDomDocument, QDomElement and QDomText.這裡不做詳細說明,

下面介紹下簡單操作,

1、首先定義QDomDocument對象,來讀取XML文檔,

        QDomDocumentdoc;

    if (!doc.setContent(&file, false, &errorStr, &errorLine,
                        &errorColumn)) {
        std::cerr << "Error: Parse error at line " << errorLine << ", "
                  << "column " << errorColumn << ": "
                  << qPrintable(errorStr) << std::endl;
        return false;
    }
2、QDomElement 來處理XML的元素,這個很重要,該類包含了對子節點的處理,插入刪除、以及遍曆都會用到它    QDomElement root = doc.documentElement();
    if (root.tagName() != "bookindex") {
        std::cerr << "Error: Not a bookindex file" << std::endl;
        return false;
    }

 

DOM讀寫XML的方式是一致的,都需要遞迴向下遍曆,這裡給出DOM寫(或者說修改)XML的代碼(http://blog.csdn.net/qustdjx/article/details/7518200):

#include<QDomDocument>

QDomDocumentm_doc;//在標頭檔中聲明

bool DomParser::changeSave()  //

{
    if(!openXmlFile("/home/qust/qt/XML/2.xml"))
        {
            return false;
        }
        //修改儲存xml
    QDomElement root = m_doc.documentElement();
       if(root.tagName()!= "kdevelop")
           return false;
       QDomNode n = root.firstChild();
       while ( !n.isNull() )
       {
           QDomElement e = n.toElement();
           if( !e.isNull())
           {
                       if( e.nodeName() == "general" )
                       {
                           QDomNodeList list = e.childNodes(); //獲得元素e的所有子節點的列表
                           for(int a=0; a<list.count(); a++) //遍曆該列表
                           {
                                 node = list.at(a);
                               if(node.isElement())
                               {
                                   if( node.nodeName() == "author" )
                                   { QDomNode oldnode = node.firstChild();     //標籤之間的內容作為節點的子節點出現,得到原來的子節點
                                       node.firstChild().setNodeValue("csdn");   //用提供的value值來設定子節點的內容//從這裡可以看出,該方法讀寫通用,QString text=node.firstChild().nodeValue();就可以讀取該節點的內容
                                       QDomNode newnode = node.firstChild();     //值修改過後
                                       node.replaceChild(newnode,oldnode);      //調用節點的replaceChild方法實現修改功能
                                   }
                                   if( node.nodeName() == "email" )
                                   {
                                       QDomNode oldnode = node.firstChild();
                                       node.firstChild().setNodeValue("[email protected]");
                                       QDomNode newnode = node.firstChild();
                                       node.replaceChild(newnode,oldnode);
                                   }
                               }
                           }
                       }
                   }
           n = n.nextSibling();
             }
             QFile filexml("/home/qust/qt/XML/2.xml");
             if( !filexml.open( QFile::WriteOnly | QFile::Truncate) ){
                 qWarning("error::ParserXML->writeOperateXml->file.open\n");
                 return false;
                    }
                    QTextStream ts(&filexml);
                    ts.reset();
                    ts.setCodec("utf-8");
                    m_doc.save(ts, 4, QDomNode::EncodingFromTextStream);
                    filexml.close();
                    return true;
}

 

 

3、SAX(XML簡單API)通過虛擬函數直接嚮應用程式報告"解析事件",是Simple API for XML的簡稱,其實現方式是按階段將文檔讀取到記憶體中,在碰到標籤或者其它階段的時候,調用開發人員預先設計好的回呼函數去處理。這種方式的缺點是需要開發 者寫回呼函數去處理不同標籤,代碼複雜一些,優點是能處理很大的XML檔案。

 

Qt中對XML的處理方式

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.