QT读写XML⽂件之DOM⽅式解析XML
版权声明:本⽂为博主原创⽂章,未经博主允许不得转载。 blog.csdn/ZuoYueXian/article/details/73088098
⼀、DOM简介
1、DOM简介
DOM是Document Object Model的简写,即XML⽂档对象模型,是由W3C提出的⼀种处理XML⽂档的标准接⼝。
DOM ⼀次性读⼊整个XML⽂档,在内存中构造为⼀棵树(DOM树)将XML⽂件表⽰成⼀棵树,便于随机访问其中的节点,但消耗内存相对多⼀些。能够在这棵树上进⾏导航,⽐如移动到下⼀节点或者返回上⼀节点,也可以对这棵树进⾏修改,或者是直接将这颗树保存为硬盘上的⼀个 XML ⽂件。
2、XML DOM节点
XML ⽂档中的每个成分都是⼀个节点,整个⽂档是⼀个⽂档节点,每个XML 标签是⼀个元素节点,包含在XML元素中的⽂本是⽂本节点, 每⼀个XML属性是⼀个属性节点,注释属于注释节点。createprocessa
QT中使⽤QDomDocument来表⽰XML⽂档,QDomElement表⽰XML⽂档的元素,QDomProcessingInstruction表⽰XML处理指令,QDomAttr表⽰元素的属性,QDomText表⽰XML⽂档中的⽂本数据。所有的DOM节点如处理指令、元素、属性和⽂本数据等,都使⽤QDomNode来表⽰,然后使⽤对应的 isProcessingI nstruction()、isElement()、isAttr()和isText()等函数来判断是否是该类型的节点,如果是,那么就可以使⽤toProcessingInstruction()、toElement()、toAttr()和t oText()等函数转换为具体类型的节点。
⽂本数据总是存储在⽂本节点中,元素节点的⽂本数据是存储在⽂本节点中的。
⼆、QDomDocument
1、QDomDocument简介
QDomDocument类⽤于显⽰XML⽂档,是⽂档树的根节点,提供了对⽂档数据的主要访问。由于元素、⽂本节点、注释、说明等不能在⽂档外部,QDomDocu ment包含了创建这些对象的⼯⼚函数。
需要解析的XML⽂档在内部显⽰为⼀棵被QDOM其它类访问的对象树。所有的QDOM类只能引⽤对象树中的对象。⼀旦或是QDomDocument根节点被删除,D OM树中的所有内部对象将被删除。
元素、⽂本节点等的创建由QDomDocument类提供的⼯⼚函数完成。使⽤默认的QDOM类的构造函数
只能得到⼀个不能操作、插⼊⽂档的空对象。
QDomDocument类有多个⽤于创建⽂档数据的函数,如createElement、createTextNode、createComment、createCDATASection、createProcessingInstru ction、createAttribute和createEntityReference。这些函数中的⼀些⽀持命名空间的版本。createDocumentFragment函数为了持有⽂档中的部分内容,对于操作复杂⽂档是很有⽤的。
设置⽂档的整体内容使⽤setContent()函数。setContent函数通过XML⽂档和创建显⽰⽂档的DOM树来解析⽂档。
对于较⼤的XML⽂档,DOM树会占⽤较⼤的内存空间。对于较⼤的XML⽂档,使⽤QXmlStreamReader或QXmlQuery会使更好的解决⽅案。
2、QDomDocument成员函数
QDomDocument::QDomDocument(const QString &name)
QDomDocument::QDomDocument(const QDomDocumentType &doctype)
QDomDocument::QDomDocument(const QDomDocument &x)
构造函数
QDomAttr QDomDocument::createAttribute(const QString &name)
创建⼀个能够插⼊到元素的名为name的新属性
QDomAttr QDomDocument::createAttributeNS(const QString &nsURI, const QString &qName)
创建⼀个能够插⼊到元素的⽀持命名空间的新属性,名字为qName,命名空间为nsURI
QDomCDATASection QDomDocument::createCDATASection(const QString &value)
创建⼀个能插⼊⽂档的值为value的新CDATA段
QDomComment QDomDocument::createComment(const QString &value)
创建⼀个能插⼊⽂档的值为value的新注释
QDomDocumentFragment QDomDocument::createDocumentFragment()
创建⼀个持有⽂档部分内容的⽂档段
QDomElement QDomDocument::createElement(const QString &tagName)
创建⼀个能插⼊DOM树的名为tagName的新元素
QDomElement QDomDocument::createElementNS(const QString &nsURI, const QString &qName)
创建⼀个能插⼊DOM树的⽀持命名空间的名为qName的新元素,命名空间为nsURI
QDomEntityReference QDomDocument::createEntityReference(const QString &name)
创建⼀个能插⼊⽂档的名为name的新实体引⽤
QDomProcessingInstruction QDomDocument::createProcessingInstruction(const QString &target, const QString &data)
创建⼀个能插⼊⽂档的新的说明,设置说明的⽬标为target,数据为data
QDomText QDomDocument::createTextNode(const QString &value)
创建⼀个能插⼊⽂档树的值为value的新⽂本节点
QDomDocumentType QDomDocument::doctype() const
返回⽂档的⽂档类型
QDomElement QDomDocument::documentElement() const
返回⽂档的根元素
QDomElement QDomDocument::elementById(const QString &elementId)
返回ID为elementId的元素
QDomNodeList QDomDocument::elementsByTagName(const QString &tagname) const
返回包含tagname⽂档的所有元素的节点链表
QDomNodeList QDomDocument::elementsByTagNameNS(const QString &nsURI, const QString &localName)
返回包含本地名为localName、命名空间为nsURI的⽂档的所有元素的节点链表
QDomImplementation QDomDocument::implementation() const
返回QDomImplementation对象
QDomNode QDomDocument::importNode(const QDomNode &importedNode, bool deep)
从另⼀个⽂档导⼊importedNode节点到⽂档,如果deep为true,导⼊importedNode节点的⼦树,否则导⼊importedNode节点。
QDomNode::NodeType QDomDocument::nodeType() const
返回节点类型
bool QDomDocument::setContent(const QByteArray &data, bool namespaceProcessing, QString *errorMsg = Q_NULLPTR, int *errorLine = Q_NULLPTR, int *errorColumn = Q_NULLPTR)
从字节数组数据data解析XML⽂档,并设置为⽂档的内容
bool QDomDocument::setContent(const QString &text, bool namespaceProcessing, QString *errorMsg = Q_NULLPTR, int *errorLine = Q_NULLPTR, int *errorColumn = Q_NULLPTR)
从字符串text中读取XML⽂档,如果成功解析了内容,返回true
bool QDomDocument::setContent(QIODevice *dev, bool namespaceProcessing, QString *errorMsg = Q_NULLPTR, int
*errorLine = Q_NULLPTR, int *errorColumn = Q_NULLPTR)
从设备dev中读取XML⽂档,如果成功解析了内容,返回true
bool QDomDocument::setContent(QXmlInputSource *source, bool namespaceProcessing, QString *errorMsg = Q_NULLPTR, int *errorLine = Q_NULLPTR, int *errorColumn = Q_NULLPTR)
从QXmlInputSource中读取XML⽂档,如果成功解析了内容,返回true
QByteArray QDomDocument::toByteArray(int indent = 1) const
返回解析后的⽂档的⽂本内容的UTF-8格式的字节数组数据
QString QDomDocument::toString(int indent = 1) const
返回解析后的⽂档的⽂本内容
三、QDomElement
1、QDomElement简介
QDomElement表⽰DOM树中的⼀个元素节点。元素有⼀个标签名和0个或多个属性。
2、QDomElement成员函数
QString QDomElement::attribute(const QString &name, const QString &defValue = QString()) const
返回元素的名字为name的属性,如果不存在,返回defValue默认值
QDomAttr QDomElement::attributeNode(const QString &name)
返回元素中名字为name的属性的QDomAttr对象
QDomNamedNodeMap QDomElement::attributes() const
返回元素中所有属性的通过名字访问属性节点的集合
QDomNodeList QDomElement::elementsByTagName(const QString &tagname) const
返回元素名为tagname的元素的所有⼦节点的前序遍历的节点链表
bool QDomElement::hasAttribute(const QString &name) const
如果元素中有名字为name的属性,返回true
void QDomElement::removeAttribute(const QString &name)
删除元素中名字为name的属性
void QDomElement::setAttribute(const QString &name, const QString &value)
在元素中添加⼀个名字为name,值为value的属性,如果已经存在,使⽤value替换值
void QDomElement::setTagName(const QString &name)
设置元素的标签名为name
QString QDomElement::tagName() const
返回元素的标签名
QString QDomElement::text() const
返回元素的⽂本
四、QDomAttr
QDomAttr表⽰元素的属性
QString QDomAttr::name() const
返回属性的名字
QDomElement QDomAttr::ownerElement() const
返回属性所属的元素节点
void QDomAttr::setValue(const QString &v)
设置属性的值为v
bool QDomAttr::specified() const
如果属性已经由⽤户设置,返回true
QString QDomAttr::value() const
返回属性的值
五、DOM⽅式操作XML⽂件
DOM⽅式解析XML⽂件先打开XML⽂件,将XML⽂件整体加载到内存中建⽴DOM树,对于XML⽂档的任何操作在内存中的DOM树直接操作,最后保存时将DOM树的所有节点写回XML⽂档。需要注意的是,通常打开XML⽂件,将XML⽂件加载到内存中建⽴DOM树
后,XML⽂件就可以关闭了。如果要保存改变后的XML⽂档内容,需要在保存时以清空⽂件的⽅式打开XML⽂件,将改变后DOM树的所有节点写⼊XML⽂件即可。
1、读取XML⽂件
<?xml version="1.0" encoding="UTF-8"?>
<library>
<book time="2013/6/13" id="1">
<title>C++ primer</title>
<author>Stanley Lippman</author>
</book>
<book time="2007/5/25" id="2">
<title>Thinking in Java</title>
<author>Bruce Eckel</author>
</book>
</library>
读取的XML⽂件的代码如下:
//打开或创建⽂件
QFile file("l");
if(!file.open(QFile::ReadOnly))
return;
QDomDocument doc;
//设置l到⽂档
if(!doc.setContent(&file))
{
file.close();
return;
}
file.close();
//返回根节点
QDomElement root=doc.documentElement();
qDebug()<&deName();
/
/获得第⼀个⼦节点
QDomNode node=root.firstChild();
while(!node.isNull())  //如果节点不空
{
if(node.isElement()) //如果节点是元素
{
//转换为元素
QDomElement Element();
qDebug()<<e.tagName()<<" "<<e.attribute("id")<<" "<<e.attribute("time");
QDomNodeList list=e.childNodes();
for(int i=0;i&unt();i++)
{
QDomNode n=list.at(i);
if(node.isElement())
qDebug()<&deName()<<":"<&Element().text();
}
}
//下⼀个兄弟节点
Sibling();
}
2、写XML⽂件