39.Qt XML
Posted 喵小喵~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了39.Qt XML相关的知识,希望对你有一定的参考价值。
1.使用QXmlStreamReader读取XML,可以读取内存中容纳不了的特大文件,或者读取在XML文档中定制的文档的内容。
xml文件(in1.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>
main.cpp
1 #include <QtGui> 2 3 #include <iostream> 4 #include "xmlstreamreader.h" 5 6 int main(int argc, char *argv[]) 7 { 8 //创建QApplication对象 9 QApplication app(argc, argv); 10 QDir::setCurrent(app.applicationDirPath());//设置路径为当前目录 11 12 //创建两个标签 13 QStringList labels; 14 labels << QObject::tr("Terms") << QObject::tr("Pages"); 15 16 //树形控件窗口 17 QTreeWidget treeWidget; 18 //设置第一行 19 treeWidget.setHeaderLabels(labels); 20 //设置可以伸缩 21 treeWidget.header()->setResizeMode(QHeaderView::Stretch); 22 //设置窗口标题 23 treeWidget.setWindowTitle(QObject::tr("XML Stream Reader")); 24 //树形控件显示 25 treeWidget.show(); 26 27 //创建对象,对xml读取 28 XmlStreamReader reader(&treeWidget); 29 30 reader.readFile("in1.xml"); 31 32 return app.exec(); 33 }
xmlstreamreader.h
1 #ifndef XMLSTREAMREADER_H 2 #define XMLSTREAMREADER_H 3 4 #include <QXmlStreamReader> 5 6 class QTreeWidget; 7 class QTreeWidgetItem; 8 9 class XmlStreamReader 10 { 11 public: 12 XmlStreamReader(QTreeWidget *tree); 13 14 bool readFile(const QString &fileName); 15 16 private: 17 //解析一个含有0或0个以上<entry>元素的<bookindex>...</bookindex> 18 void readBookindexElement(); 19 //解析一个含有0个或0个以上<entry>元素的<entry>...</entry>元素 20 //以及嵌套任意层次的含有0或0个以上<entry>元素 21 void readEntryElement(QTreeWidgetItem *parent); 22 //解析一个<page>...</page>元素 23 void readPageElement(QTreeWidgetItem *parent); 24 //跳过不能识别的元素 25 void skipUnknownElement(); 26 27 //保存传进来的treeWidget 28 QTreeWidget *treeWidget; 29 //读取对象 30 QXmlStreamReader reader; 31 }; 32 33 #endif
xmlstreamreader.cpp
1 #include <QtGui> 2 #include <QtXml> 3 #include <iostream> 4 5 #include "xmlstreamreader.h" 6 7 XmlStreamReader::XmlStreamReader(QTreeWidget *tree) 8 { 9 //初始化指针 10 treeWidget = tree; 11 } 12 13 bool XmlStreamReader::readFile(const QString &fileName) 14 { 15 //尝试打开文件 16 QFile file(fileName); 17 //只读,文本方式打开。如果出错,返回出错信息。 18 if (!file.open(QFile::ReadOnly | QFile::Text)) { 19 std::cerr << "Error: Cannot read file " << qPrintable(fileName) 20 << ": " << qPrintable(file.errorString()) 21 << std::endl; 22 return false; 23 } 24 25 //如果成功,则将这个file设置为输入设备,用于读数据 26 reader.setDevice(&file); 27 28 //从流中读取一个数据 29 reader.readNext(); 30 //如果没到文件末尾 31 while (!reader.atEnd()) { 32 //如果是开始标签 33 if (reader.isStartElement()) { 34 if (reader.name() == "bookindex") { 35 //解析bookindex 36 readBookindexElement(); 37 } 38 else 39 { 40 //否则给出出错信息 41 reader.raiseError(QObject::tr("Not a bookindex file")); 42 } 43 } 44 else 45 { 46 //继续读下一个标签 47 reader.readNext(); 48 } 49 } 50 51 file.close(); 52 //如果处理出现错误就会返回 53 //是否存在解析错误? 54 if (reader.hasError()) { 55 std::cerr << "Error: Failed to parse file " 56 << qPrintable(fileName) << ": " 57 << qPrintable(reader.errorString()) << std::endl; 58 return false; 59 } 60 //是否存在文件错误? 61 else if (file.error() != QFile::NoError) 62 { 63 std::cerr << "Error: Cannot read file " << qPrintable(fileName) 64 << ": " << qPrintable(file.errorString()) 65 << std::endl; 66 return false; 67 } 68 return true; 69 } 70 71 void XmlStreamReader::readBookindexElement() 72 { 73 //读下一个标签 74 reader.readNext(); 75 while (!reader.atEnd()) { 76 //如果到结束标签,则结束while循环 77 if (reader.isEndElement()) { 78 reader.readNext(); 79 break; 80 } 81 82 83 //如果是开始标签 84 if (reader.isStartElement()) 85 { 86 if (reader.name() == "entry") 87 { 88 //调用处理entry的函数 89 readEntryElement(treeWidget->invisibleRootItem()); 90 } 91 else 92 { 93 //调用未知的处理函数 94 skipUnknownElement(); 95 } 96 } 97 else 98 { 99 //如果不是开始标签则读取下一个 100 reader.readNext(); 101 } 102 } 103 } 104 105 //每当遇到<entry>开始标签,就调用readEntryElement()函数 106 void XmlStreamReader::readEntryElement(QTreeWidgetItem *parent) 107 { 108 //遇到一个<entry>就在树形控件中增加一个条目 109 QTreeWidgetItem *item = new QTreeWidgetItem(parent); 110 //设置第0个,为对应的term项所表示的值 111 item->setText(0, reader.attributes().value("term").toString()); 112 113 //读下一个 114 reader.readNext(); 115 while (!reader.atEnd()) { 116 //如果遇到关闭标签,跳出循环 117 if (reader.isEndElement()) { 118 reader.readNext(); 119 break; 120 } 121 122 //如果遇到的是开始标签 123 if (reader.isStartElement()) { 124 //如果是<entry>标签 125 if (reader.name() == "entry") { 126 //递归调用 127 readEntryElement(item); 128 } 129 //如果是<page>标签 130 else if (reader.name() == "page") 131 { 132 readPageElement(item); 133 } 134 //未知标签 135 else 136 { 137 skipUnknownElement(); 138 } 139 } 140 else 141 { 142 reader.readNext(); 143 } 144 } 145 } 146 147 //读取页面信息 148 void XmlStreamReader::readPageElement(QTreeWidgetItem *parent) 149 { 150 //读标签内容,调用reader.readElementText,reader会停留在结束标签位置上,需要跳过 151 QString page = reader.readElementText(); 152 //如果是结束标识,则跳到下一个进行读取 153 if (reader.isEndElement()) 154 reader.readNext(); 155 156 //第一个文本 157 QString allPages = parent->text(1); 158 //如果不为空加上, 159 if (!allPages.isEmpty()) 160 allPages += ", "; 161 //加上标签内容 162 allPages += page; 163 //设置 164 parent->setText(1, allPages); 165 } 166 167 //如果遇到未知标签也读取,直到跳过该标签的关闭标签 168 void XmlStreamReader::skipUnknownElement() 169 { 170 //遇到未知的继续读取下一个标签 171 reader.readNext(); 172 //继续读下一个,如果没到末尾 173 while (!reader.atEnd()) { 174 if (reader.isEndElement()) { 175 reader.readNext(); 176 break; 177 } 178 179 //如果是开始,继续递归,直到遇到第一个未知的关闭标签 180 if (reader.isStartElement()) { 181 skipUnknownElement(); 182 } else { 183 reader.readNext(); 184 } 185 } 186 }
以上是关于39.Qt XML的主要内容,如果未能解决你的问题,请参考以下文章
xml Eclipse模板(代码片段)检查参数并最终抛出IllegalArgumentException