XML(eXtensible Markup Language,可扩展标记语言)是普通用于数据交换和数据存储的一种多用途文本文件格式;

SVG(可标量矢量图形)XML格式,QtSvg模块提供了可用于载入并呈现SVG图像的类;

MathML(数学标记语言)XML格式的绘制文档,可以使用Qt Solution中的QtMmlWidget操作;

对于一般的XML数据处理,Qt提供了QtXml模块,QtXml提供了三种不同的应用程序接口来读取XML文档:

1、QXmlStreamReader

用于读取格式良好的XML文档的快速解析器,该类最快且最易于使用,并提供了与其他Qt兼容的应用程序编程接口,很适用于编写单通道解析器;

下图是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("test@tom.com");
                                       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简单应用程序编程接口)通过虚拟函数直接向应用程序报告"解析事件",这里没有做具体说明,用到再做总结。

Qt XML读取写入操作的更多相关文章

  1. Python文件的读取写入操作

    一.打开文件.关闭文件操作 想要读取文件或是写入文件,第一步便是打开文件,最后一步便是关闭文件.这里介绍两种打开(关闭)文件的方式: 1.open()方法 f=open(file_name[,acce ...

  2. 人生苦短_我用Python_configparser/yaml对配置文件读取/写入操作_010

    第一,我们先开始安装yaml库,configparser是自带库,yaml库是针对读取yml文件,configparser现阶段我只用于读取conf文件 首先:1)对象文件为:data.yml,下面的 ...

  3. c#cookie读取写入操作

    public static void SetCookie(string cname, string value, int effective) { HttpCookie cookie = new Ht ...

  4. 关于Python中读取写入文件并进行文件与用户交互的操作

    一.提前知识点 在python中是同样和其他语言一样可以进行文件的读取写入操作,值得注意的是,Python中打开文件读取的方式有几种,分别是以下几种: f = open('username.txt') ...

  5. [Python] python3 文件操作:从键盘输入、打开关闭文件、读取写入文件、重命名与删除文件等

    1.从键盘输入 Python 2有两个内置的函数用于从标准输入读取数据,默认情况下来自键盘.这两个函数分别是:input()和raw_input(). Python 3中,不建议使用raw_input ...

  6. java===java基础学习(5)---文件读取,写入操作

    文件的写入读取有很多方法,今天学到的是Scanner和PrintWriter 文件读取 Scanner in = new Scanner(Paths.get("file.txt") ...

  7. Python文件操作:文件的打开关闭读取写入

    Python文件操作:文件的打开关闭读取写入 一.文件的打开关闭 Python能以文本和二进制两种方式处理文件,本文主要讨论在Python3中文本文件的操作. 文件操作都分为以下几个步骤: 1.打开文 ...

  8. Qt QtXml读取xml文件内容

    Qt QtXml读取xml文件内容 xml文件内容 <?xml version="1.0" encoding="UTF-8"?> <YG_RT ...

  9. winform,xml读取与写入

    创建两个xml文件,一个 xml做为模板配置项,另一个做为临时接收数据. private static string localPath = System.Environment.CurrentDir ...

随机推荐

  1. [Python笔记]第十六篇:web框架之Tornado

    Tornado是一个基于python的web框架,xxxxx 安装 python -m pip install tornado 第一个Tornado程序 安装完毕我们就可以新建一个app.py文件,放 ...

  2. CodeChef CBAL

    题面: https://www.codechef.com/problems/CBAL 题解: 可以发现,我们关心的仅仅是每个字符出现次数的奇偶性,而且字符集大小仅有 26, 所以我们状态压缩,记 a[ ...

  3. Scut:账号服务器问题修正

    姑且记录一下,以防未来出现bug回来看看今天改了哪些. 原 Scut 账服是应用于 渠道频道 的账号服务器,每天会发放大量的游客账号,它有一个"自动将已经被注册了一段时间的游客账号再重新推送 ...

  4. nutch 二次开发

    /*深度控制*/ 深度控制:nutch是广域网的深度遍历,我们需要的是垂直采集(即只采集某一个栏目),举例,索引页总计20页,如果只有下一页,则深度为20,如果是1 2 3 4 5……20则深度为2即 ...

  5. js compress and combine

    http://www.cnblogs.com/snandy/archive/2012/06/08/2541827.html http://developer.51cto.com/art/201301/ ...

  6. Android 两个Activity进行数据传送 发送

    Activity1:: Intent intent= new Intent(this, OtherActivity.class); String name = "heyiyong" ...

  7. Qt 中update()和repaint()的区别

    void QWidget::repaint ( int x, int y, int w, int h, bool erase = TRUE ) [槽]通过立即调用paintEvent()来直接重新绘制 ...

  8. Linux启动或禁止SSH用户及IP的登录

    启动或禁止SSH用户登录 一般情况下,在使用Linux操作系统都不会去机房来操作机器,都是使用一些第三方的工具来操作. 比如使用SSH Secure File Transfer Client工具来传输 ...

  9. Installing vSphere SDK for Perl

    Installing vSphere SDK for Perl 你可以安装vSphere SDK 在Linux 或者Microsoft Windows 系统,或者 部署 VSphere Managem ...

  10. 折腾iPhone的生活——运营商信号显示数据化

    iOS7以后iphone的信号都是用5个小圆圈显示的,像这样 但是还有种显示方法可以用数字信号显示信号量,比较适合很专注于生活品质的人和对数字有偏爱的人,像这样: 这样还有个好处是可以节约顶部状态栏的 ...