Qt Gui 第十六章
一、QXmlStreamReader
用于读取格式良好的xml文档的快速解析器;解析步骤
QXmlStreamReader reader;
QFile file(fileName);
reader.setDevice(&file);
如上将xml文件加载到reader中;也可以直接 QXmlStreamReader reader(&file);
接下去可以遍历xml节点;通过 reader.readNext(); 顺序遍历每一个节点;返回的类型可以有
Invalid,
StartDocument,
EndDocument,
StartElement,
EndElement,
Characters,
Comment,
DTD,
EntityReference,
ProcessingInstruction
也可以通过判断是否是自己想要的类型如: reader.atEnd()、reader.isEndElement()、reader.isStartElement()等类型判断是否到自己想要的位置;atEnd是指当前层的节点已经遍历完了;isEndElement是指当前节点已经遍历了(主要是指子节点也遍历完了)
reader.name()获取到当前节点的名字;reader.attributes().value("term").toString()获取指定属性的值,如term属性的值;reader.readElementText()则是读取节点的text;
例如读取如下的xml数据:
<entry term="sidebearings"> <page>10</page> </entry>
1、readNext读取到<entry term="sidebearings">;然后通过reader.attributes().value("term").toString()则会返回sidebearings;
2、readNext读取到“\n ”这里我用双引号标出来;则readNext返回的type是Characters
3、readNext读取到的是<page>10</page>;然后通过reader.readElementText()读取到10这个字符串;
4、readNext读取到“\n”,readNext返回的type是Characters
5、readNext读取到的是</entry>;readNext返回的类型是EndElement
6、readNext读取到“”,其实啥都没有读取到,返回的类型是EndElement,但是atEnd标记的是true;(这里不管读到的是还有其他字符与否,atEnd都直接标记true)
二、DOM
是一种解析由万维网协会(W3C)所开发的xml文档的标准应用程序编程接口。
QDomDocument doc; doc.setContent(&file, false, &errorStr, &errorLine, &errorColumn); QDomElement root = doc.documentElement(); QDomNode child = root.firstChild(); //然后遍历当前层的所有孩子 while (!child.isNull()) { if (child.toElement().tagName() == "entry") parseEntryElement(child.toElement(),treeWidget->invisibleRootItem()); child = child.nextSibling(); }
1、声明一个文档的dom:doc
2、然后doc.setContent则是解析了整个xml文件;接下去无需再读取文件的操作。
3、获取doc的QDomElement,即获取xml的第一层的element
4、然后获取root.firstChild()获取第一层element的子节点,将子节点当成一个node;当要查找下一个兄弟节点,则是 child.nextSibling();
5、将node抓换成element
。。。。然后遍历递归所有子节点;
element.attribute("term")获取属性term的值;如果有多个属性的时候,可以通过
QDomNamedNodeMap node_map = element.attributes(); for (int i = 0; i < node_map.count(); ++i) { QDomNode node = node_map.item(i); QDomAttr atr = node.toAttr(); atr.value(); atr.name(); }
获取所有的属性,然后遍历所有的属性;也可以通过node_map.namedItem(const QString& name)来获取对应的QDomNode
要获取对应的标签名字:child.toElement().tagName()
三、QXmlDefaultHandler
该函数是通过继承来处理自己想要读取的节点的信息;

class Q_XML_EXPORT QXmlDefaultHandler : public QXmlContentHandler, public QXmlErrorHandler, public QXmlDTDHandler, public QXmlEntityResolver, public QXmlLexicalHandler, public QXmlDeclHandler { public: QXmlDefaultHandler() { } virtual ~QXmlDefaultHandler() { } void setDocumentLocator(QXmlLocator* locator); bool startDocument(); bool endDocument(); bool startPrefixMapping(const QString& prefix, const QString& uri); bool endPrefixMapping(const QString& prefix); bool startElement(const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& atts); bool endElement(const QString& namespaceURI, const QString& localName, const QString& qName); bool characters(const QString& ch); bool ignorableWhitespace(const QString& ch); bool processingInstruction(const QString& target, const QString& data); bool skippedEntity(const QString& name); bool warning(const QXmlParseException& exception); bool error(const QXmlParseException& exception); bool fatalError(const QXmlParseException& exception); bool notationDecl(const QString& name, const QString& publicId, const QString& systemId); bool unparsedEntityDecl(const QString& name, const QString& publicId, const QString& systemId, const QString& notationName); bool resolveEntity(const QString& publicId, const QString& systemId, QXmlInputSource*& ret); bool startDTD(const QString& name, const QString& publicId, const QString& systemId); bool endDTD(); bool startEntity(const QString& name); bool endEntity(const QString& name); bool startCDATA(); bool endCDATA(); bool comment(const QString& ch); bool attributeDecl(const QString& eName, const QString& aName, const QString& type, const QString& valueDefault, const QString& value); bool internalEntityDecl(const QString& name, const QString& value); bool externalEntityDecl(const QString& name, const QString& publicId, const QString& systemId); QString errorString() const; private: QXmlDefaultHandlerPrivate *d; Q_DISABLE_COPY(QXmlDefaultHandler) };
如上的QXmlDefaultHandler头文件代码所示,看自己需要的信息是什么,通过继承对应的函数来获取;
举个例子:
假设子类继承了QXmlDefaultHandler的四个函数,如下
bool startElement(const QString &namespaceURI, const QString &localName, const QString &qName, const QXmlAttributes &attributes); bool endElement(const QString &namespaceURI, const QString &localName, const QString &qName); bool characters(const QString &str); bool fatalError(const QXmlParseException &exception);
然后实现自定义的函数readFile
bool SaxHandler::readFile(const QString &fileName) { currentItem = 0; QFile file(fileName); QXmlInputSource inputSource(&file); QXmlSimpleReader reader; reader.setContentHandler(this); reader.setErrorHandler(this); return reader.parse(inputSource); }
这里的reader有两个setXXXHandler,那是因为我们重新实现了对应的Content类里面的函数startElement、endElement、characters;对应的Error类里面的fatalError函数;查看具体用到哪些类的函数,可以看QXmlDefaultHandler所在的头文件;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!