Qt XML 读写示例

Qt XML 读写

XML 简介

XML(Extensible Markup Language)是一种类似于 HTML,但是没有使用预定义标记的语言。
有许多基于 XML 的语言,包括 XHTML、MathML、SVG、RSS 和 RDF (en-US)。

XML 声明

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

注释

<!-- Comment -->

实体

像 HTML 一样,XML 为一些特别预留的符号定义了一些方法,称为实体(entities),例如用于标记的大于号。下面是五个你必须知道的符号:

实体 符号 描述
& lt; < 小于符号
& gt; > 大于符号
& amp; &
& quot; " 一个双引号
& apos; ' 一个单引号

Qt QDomDocument

示例

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <tag id="1" time="2013/6/13">
    <name>test1</name>
    <value>100</value>
  </tag>
  <tag id="2" time="1813/1/27">
    <name>test2</name>
    <value>100</value>
  </tag>
</root>

Code


void QtDemo::on_writeXmlBtn_Clicked()
{
    //The trick of setting the QT_HASH_SEED environment variable
    qSetGlobalQHashSeed(0); // set a fixed hash value

    //打开或创建文件
    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("root");
    doc.appendChild(root);
    //添加第一个子节点及其子元素
    QDomElement tag = doc.createElement("tag");
    tag.setAttribute("id", 1); //方式一:创建属性  其中键值对的值可以是各种类型
    QDomAttr time = doc.createAttribute("time"); //方式二:创建属性 值必须是字符串
    time.setValue("2011/1/11");
    tag.setAttributeNode(time);
    QDomElement name = doc.createElement("name"); //创建子元素
    QDomText text; //设置括号标签中间的值
    text = doc.createTextNode("test1");
    tag.appendChild(name);
    name.appendChild(text);
    QDomElement value = doc.createElement("value"); //创建子元素
    text = doc.createTextNode("100");
    value.appendChild(text);
    tag.appendChild(value);
    root.appendChild(tag);

    //添加第二个子节点及其子元素,部分变量只需重新赋值
    tag = doc.createElement("tag");
    tag.setAttribute("id", 2);
    time = doc.createAttribute("time");
    time.setValue("2002/2/2");
    tag.setAttributeNode(time);
    name = doc.createElement("name");
    text = doc.createTextNode("test2");
    tag.appendChild(name);
    name.appendChild(text);
    value = doc.createElement("value");
    text = doc.createTextNode("200");
    value.appendChild(text);
    tag.appendChild(value);
    root.appendChild(tag);

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

    // reset hash seed with new random value.
    qSetGlobalQHashSeed(-1);
}

void QtDemo::onreadxmlclicked()
{
    //打开或创建文件
    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 QtDemo::on_addXmlBtn_Clicked()
{
    //打开文件
    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("tag");
    book.setAttribute("id", 3);
    book.setAttribute("time", "2019/1/1");
    QDomElement title = doc.createElement("name");
    QDomText text;
    text = doc.createTextNode("test3");
    title.appendChild(text);
    book.appendChild(title);
    QDomElement author = doc.createElement("value");
    text = doc.createTextNode("300");
    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 QtDemo::on_removeXmlBtn_Clicked()
{
    //打开文件
    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("tag"); //由标签名定位
    for (int i = 0; i < list.count(); i++)
    {
        QDomElement e = list.at(i).toElement();
        if (e.attribute("id") == "1")  //以属性名定位,类似于hash的方式,warning:这里仅仅删除一个节点,其实可以加个break
            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 QtDemo::on_updateXmlBtn_Clicked()
{
    //打开文件
    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("tag");
    QDomNode node = list.at(list.size() - 1).firstChild(); //定位到第三个一级子节点的子元素
    QDomNode oldnode = node.firstChild(); //标签之间的内容作为节点的子节点出现,当前是
    node.firstChild().setNodeValue("test333");
    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();
}

参考链接

转载请注明出处。以上只代表个人观点,引用不当或侵权请联系删除。

posted @ 2023-05-08 16:38  yg1990  阅读(33)  评论(0编辑  收藏  举报