70 DOM读取XML

DOM(Document Object Model,文档对象模型),是W3C的推荐标准。它提供了一个接口来访问和改变一个XML文件的内容和结构,可以将XML文档表示为一个存储在内存中具有层次的树视图。文档本身由QDomDocument对象来表示,而文档树中所有的DOM节点都是QDomNode类的子类。

在Qt中使用QDomProcessingInstruction类来表示XML说明。元素对应QDomElement类。属性对应QDomAttr类。文本内容由QDomText类表示。所有的DOM节点,比如这里的说明、元素、属性和文本等,都使用QDomNode来表示。

元素对应QDomElement 类。元素可以包含属性,用来描述元素的相关信息,属性名和属性值在元素的起始标签中给出。

属性值必须在单引号或者双引号中。属性对应QDomAttr 类。

元素中可以包含子元素,也可以只包含文本内容,比如这里<first-name> Mary </first-name>中的Mary就是文本内容,文本内容由QDomText 类表示。

 

QDomAttr

表示一个 QDomElement 的属性

QDomCDATASection

表示一个 XML CDATA 部分

QDomCharacterData

表示 DOM 中的一个通用字符串

QDomComment

表示一个 XML 注释

QDomDocument

表示一个 XML 文档

QDomDocumentFragment

QDomNodes 树,通常不是一个完整的 QDomDocument

QDomDocumentType

表示文档树中的 DTD

QDomElement

表示 DOM 树中的一个元素

QDomEntity

代表一个 XML 实体

QDomEntityReference

代表一个 XML 实体引用

QDomImplementation

DOM 实现的功能的信息

QDomNamedNodeMap

包含一个节点集合,节点可以通过名字来访问

QDomNode

一个 DOM 树中所有节点的基类

QDomNodeList

QDomNode 对象列表

QDomNotation

代表一个 XML 表示法

QDomProcessingInstruction

代表 XML 处理指令

QDomText

表示解析的 XML 文档中的文本数据

利用实例和函数实现XMl文件的增、删、改、查

注意:

需要在pro文件里面添加QT+=xml,include <QtXml>,也可以include <QDomDocument>。对于VS2013+Qt5.5开发而言,就需要在models中勾选XML模块。

写***********

void Widget::testDomWrite()
{
    //打开或创建文件
        QFile file("test.xml"); //相对路径、绝对路径、资源路径都可以
        if(!file.open(QFile::WriteOnly|QFile::Truncate)) //可以用QIODevice,Truncate表示清空原来的内容
            return;

        QDomDocument doc;
        //写入xml头部
        QDomProcessingInstruction instruction; //添加处理命令
        instruction=doc.createProcessingInstruction("xml","version=\"1.0\" encoding=\"UTF-8\"");
        doc.appendChild(instruction);
        //添加根节点
        QDomElement root=doc.createElement("library");
        doc.appendChild(root);
        //添加第一个子节点及其子元素
        QDomElement book=doc.createElement("book");
        book.setAttribute("id",1); //方式一:创建属性  其中键值对的值可以是各种类型
        QDomAttr time=doc.createAttribute("time"); //方式二:创建属性 值必须是字符串
        time.setValue("2013/6/13");
        book.setAttributeNode(time);
        QDomElement title=doc.createElement("title"); //创建子元素
        QDomText text; //设置括号标签中间的值
        text=doc.createTextNode("C++ primer");
        book.appendChild(title);
        title.appendChild(text);
        QDomElement author=doc.createElement("author"); //创建子元素
        text=doc.createTextNode("Stanley Lippman");
        author.appendChild(text);
        book.appendChild(author);
        root.appendChild(book);

        //添加第二个子节点及其子元素,部分变量只需重新赋值
        book=doc.createElement("book");
        book.setAttribute("id",2);
        time=doc.createAttribute("time");
        time.setValue("2007/5/25");
        book.setAttributeNode(time);
        title=doc.createElement("title");
        text=doc.createTextNode("Thinking in Java");
        book.appendChild(title);
        title.appendChild(text);
        author=doc.createElement("author");
        text=doc.createTextNode("Bruce Eckel");
        author.appendChild(text);
        book.appendChild(author);
        root.appendChild(book);

        //输出到文件
        QTextStream out_stream(&file);
        doc.save(out_stream,4); //缩进4格
        file.close();
}

读***********

void Widget::testDomRead()
{
    //打开或创建文件
        QFile file("test.xml"); //相对路径、绝对路径、资源路径都行
        if(!file.open(QFile::ReadOnly))
            return;

        QDomDocument doc; //一次性的把内容都读进来
        if(!doc.setContent(&file))
        {
            file.close();
            return;
        }
        file.close();

        QDomElement root=doc.documentElement(); //返回根节点
        qDebug()<<root.nodeName();
        QDomNode node=root.firstChild(); //获得第一个子节点
        while(!node.isNull())  //如果节点不空
        {
            if(node.isElement()) //如果节点是元素
            {
                QDomElement e=node.toElement(); //转换为元素,注意元素和节点是两个数据结构,其实差不多
                qDebug()<<e.tagName()<<" "<<e.attribute("id")<<" "<<e.attribute("time"); 
                                              //打印键值对,tagName和nodeName是一个东西
                QDomNodeList list=e.childNodes();
                for(int i=0;i<list.count();i++) //遍历子元素,count和size都可以用,可用于标签数计数
                {
                    QDomNode n=list.at(i);
                    if(node.isElement())
                        qDebug()<<n.nodeName()<<":"<<n.toElement().text();
                }
            }
            node=node.nextSibling(); //下一个兄弟节点,nextSiblingElement()是下一个兄弟元素,都差不多
        }
}

添加**********

void Widget::testDomAdd()
{
    //打开文件
       QFile file("test.xml"); //相对路径、绝对路径、资源路径都可以
       if(!file.open(QFile::ReadOnly))
           return;

       //增加一个一级子节点以及元素
       QDomDocument doc;
       if(!doc.setContent(&file))
       {
           file.close();
           return;
       }
       file.close();

       QDomElement root=doc.documentElement();
       QDomElement book=doc.createElement("book");
       book.setAttribute("id",3);
       book.setAttribute("time","1813/1/27");
       QDomElement title=doc.createElement("title");
       QDomText text;
       text=doc.createTextNode("Pride and Prejudice");
       title.appendChild(text);
       book.appendChild(title);
       QDomElement author=doc.createElement("author");
       text=doc.createTextNode("Jane Austen");
       author.appendChild(text);
       book.appendChild(author);
       root.appendChild(book);

       if(!file.open(QFile::WriteOnly|QFile::Truncate)) //先读进来,再重写,如果不用truncate就是在后面追加内容,就无效了
           return;
       //输出到文件
       QTextStream out_stream(&file);
       doc.save(out_stream,4); //缩进4格
       file.close();
}

删除***************

void Widget::testDomRemove()
{
    //打开文件
        QFile file("test.xml"); //相对路径、绝对路径、资源路径都可以
        if(!file.open(QFile::ReadOnly))
            return;

        //删除一个一级子节点及其元素,外层节点删除内层节点与此相同
        QDomDocument doc;
        if(!doc.setContent(&file))
        {
            file.close();
            return;
        }
        file.close();  //一定要记得关掉啊,不然无法完成操作

        QDomElement root=doc.documentElement();
        QDomNodeList list=doc.elementsByTagName("book"); //由标签名定位
        for(int i=0;i<list.count();i++)
        {
            QDomElement e=list.at(i).toElement();
            if(e.attribute("time")=="2007/5/25")  //以属性名定位,类似于hash的方式
                root.removeChild(list.at(i));
        }

        if(!file.open(QFile::WriteOnly|QFile::Truncate))
            return;
        //输出到文件
        QTextStream out_stream(&file);
        doc.save(out_stream,4); //缩进4格
        file.close();
}

更新*******************

void Widget::testDomUpdate()
{
    //打开文件
       QFile file("test.xml"); //相对路径、绝对路径、资源路径都可以
       if(!file.open(QFile::ReadOnly))
           return;

       //更新一个标签项,如果知道xml的结构,直接定位到那个标签上定点更新
       //或者用遍历的方法去匹配tagname或者attribut,value来更新
       QDomDocument doc;
       if(!doc.setContent(&file))
       {
           file.close();
           return;
       }
       file.close();

       QDomElement root=doc.documentElement();
       QDomNodeList list=root.elementsByTagName("book");
       QDomNode node=list.at(list.size()-1).firstChild(); //定位到第三个一级子节点的子元素
       QDomNode oldnode=node.firstChild(); //标签之间的内容作为节点的子节点出现,当前是Pride and Projudice
       node.firstChild().setNodeValue("Emma");
       QDomNode newnode=node.firstChild();
       node.replaceChild(newnode,oldnode);

       if(!file.open(QFile::WriteOnly|QFile::Truncate))
           return;
       //输出到文件
       QTextStream out_stream(&file);
       doc.save(out_stream,4); //缩进4格
       file.close();
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值