qt解析xml(2)-----DOM读取xml
QDomDocument
DOM把xml文件表示成内存中的一棵树,我们可以按需要遍历这个dom树,也可以修改这个树并把它作为xml文件保存到磁盘中。由于元素、文本节点、注释、指令执行等等不可能脱离一个文档的上下文,所以文档类也包含了需要用来创建这些对象的工厂方法。被创建的节点对象有一个ownerDocument()函数,它将对象与对象常见的文档上下文环境关联起来。DOM类中最常使用的是QDomNode、QDomDocument、QDomElement和QDomText。
解析后的XML文件在内部是通过一个对象树来表示的,对象树可以使用各种QDom类进行访问。所有的QDom类只引用内部树上的对象。一旦最后一个DOM树的QDom对象和QDocument本身被删除掉时,DOM树上的所有内部对象会被删除掉。元素、文本节点等的创建是通过使用类提供的各种工厂方法完成的。使用QDom类的缺省构造函数只会生成空的对象,这些空的对象不能操作,也不能写入到文档中。
QDomDocument::setContent()完成XML文档的设置,他从QFile对象中读取XML数据并检测XML文档的编码。setContent()有几种重载形式,可以分别从QByteArray、QString、QIODevice、QXmlInputSource中读取XML数据。
QDomDocument类表示整个XML文档。从概念上讲,它是文档树的根,并提供对文档数据的主要访问。
因为元素,文本节点,注释,处理指令等不能存在于文档的上下文之外,所以文档类还包含创建这些对象所需的工厂函数。创建的节点对象具有一个ownerDocument()函数,它将它们与在其上下文中创建的文档相关联。最常用的DOM类是QDomNode,QDomDocument,QDomElement和QDomText。
解析的XML在内部由可以使用各种QDom类访问的对象树表示。所有QDom类只引用内部树中的对象。一旦引用它们的最后一个QDom对象或QDomDocument本身被删除,DOM树中的内部对象将被删除。
元素,文本节点等的创建使用此类中提供的各种工厂函数完成。使用QDom类的默认构造函数只会导致无法操作或插入到Document中的空对象。
QDomDocument类具有用于创建文档数据的多个函数,例如createElement(),createTextNode(),createComment(),createCDATASection(),createProcessingInstruction(),createAttribute()和createEntityReference()。其中一些功能具有支持命名空间的版本,即createElementNS()和createAttributeNS()。 createDocumentFragment()函数用于保存文档的各部分;这对于处理复杂文档很有用。
文档的整个内容使用setContent()设置。此函数解析作为XML文档传递的字符串,并创建表示文档的DOM树。根元素可以使用documentElement()。文档的文本表示可以使用toString()获取。
注意:如果XML文档很大,DOM树可能最终会保留大量内存。对于这样的文档,QXmlStreamReader或QXmlQuery类可能是更好的解决方案。
可以使用importNode()将来自另一个文档的节点插入到文档中。
您可以获取具有elementByTagName()或elementsByTagNameNS()的特定标记的所有元素的列表。
QDom类通常使用如下:
QDomDocument doc("mydocument");
QFile file("mydocument.xml");
if (!file.open(QIODevice::ReadOnly))
return;
if (!doc.setContent(&file)) {
file.close();
return;
}
file.close();
// print out the element names of all elements that are direct children
// of the outermost element.
QDomElement docElem = doc.documentElement();
QDomNode n = docElem.firstChild();
while(!n.isNull()) {
QDomElement e = n.toElement(); // try to convert the node to an element.
if(!e.isNull()) {
cout << qPrintable(e.tagName()) << endl; // the node really is an element.
}
n = n.nextSibling();
}
// Here we append a new element to the end of the document
QDomElement elem = doc.createElement("img");
elem.setAttribute("src", "myimage.png");
docElem.appendChild(elem);
一旦doc和elem超出范围,代表XML文档的整个内部树将被删除。
要使用DOM创建文档,请使用如下代码:
QDomDocument doc("MyML");
QDomElement root = doc.createElement("MyML");
doc.appendChild(root);
QDomElement tag = doc.createElement("Greeting");
root.appendChild(tag);
QDomText t = doc.createTextNode("Hello World");
tag.appendChild(t);
QDomDocument doc;使用doc.setContent(&file, false, &error, &row, &column),把文件传入到document中。
获取根节点:QDomElement root = doc.documentElement();
<USER NAME="root1" PASSWORD="1234567">777777777777</USER>
root.tagName() 使用tagname获取:USER
root.text():获取的是当前节点下所有子的element,也就是777777777
QDomNode node = root.firstChild(); 通过node进行遍历,然后判断node是否为空,
QDomElement element = node.toElement();通过node.toElement();可以转换成QDomelement,
通过domelement可以获取attribute;此attribute就是NAME="root1" PASSWORD="1234567"这些东西。
nodeson = nodeson.nextSibling();通过.nextSibling()都是获取下一个节点,类似于QXMLStreamReader的next。
QDomNode 详细说明
子类:QDomAttr, QDomCharacterData, QDomDocument, QDomDocumentFragment, QDomDocumentType, QDomElement, QDomEntity, QDomEntityReference, QDomNotation, QDomProcessingInstruction
QDomNode类是DOM树中所有节点的基类。
DOM中的许多函数返回一个QDomNode。
您可以使用isAttr(),isCD(),isDocumentFragment(),isDocument(),isDocumentType(),isElement(),isEntityReference(),isText(),isEntity(),isNotation() isProcessingInstruction(),isCharacterData()和isComment()获取节点的类型。
可以使用toAttr(),toCDATASection(),toDocumentFragment(),toDocument(),toDocumentType(),toElement(),toEntityReference(),toText(),toEntity(),toNotation(),将QDomNode转换为其子类之一。 ,toProcessingInstruction(),toCharacterData()或toComment()。您可以使用clear()将节点转换为空节点。
QDomNode类的副本使用显式共享共享其数据。这意味着修改一个节点将会更改所有副本。这特别适用于返回QDomNode的函数,例如firstChild()。您可以使用cloneNode()创建一个独立(深入)的节点副本。
一个QDomNode可以是null,很像一个空指针。创建一个空节点的副本会导致另一个空节点。不可能修改空节点,但可以为其分配另一个可能非空节点。在这种情况下,空节点的副本将保持为空。您可以通过调用isNull()来检查QDomNode是否为空。 QDomNode(或任何派生类)的空构造函数创建一个空节点。
节点插入insertBefore(),insertAfter()或appendChild()。您可以使用replaceChild()替换另一个节点,并使用removeChild()删除节点。
要遍历节点,请使用firstChild()获取一个节点的第一个子节点(如果有的话),nextSibling()遍历。 QDomNode还提供lastChild(),previousSibling()和parentNode()。要找到具有特定节点名称的第一个子节点使用namedItem()。
要查看节点是否有子节点使用hasChildNodes(),并获取一个节点的子节点列表,使用childNodes()。
nodeName()和nodeValue()返回节点的名称和值(其含义取决于其类型)。节点的类型由nodeType()返回。可以使用setNodeValue()设置节点的值。
该节点所属的文档由ownerDocument()返回。
可以将相邻的QDomText节点合并到具有normalize()的单个节点中。
QDomElement节点具有可以使用attributes()检索的属性。
QDomElement和QDomAttr节点可以具有可以使用namespaceURI()检索的命名空间。使用localName()检索其本地名称,并使用prefix()检索其前缀。可以使用setPrefix()设置前缀。
您可以使用save()将节点的XML表示形式写入文本流。
QDomDocument d;
d.setContent(someXML);
QDomNode n = d.firstChild();
while (!n.isNull()) {
if (n.isElement()) {
QDomElement e = n.toElement();
cout << "Element name: " << e.tagName() << endl;
break;
}
n = n.nextSibling();
}
QDomElement 详细说明
QDomElement类表示DOM树中的一个元素。
元素具有tagName()和与它们相关联的零个或多个属性。 标签名称可以用setTagName()更改。
元素属性由QDomAttr对象表示,可以使用attribute()和attributeNode()函数进行查询。 您可以使用setAttribute()和setAttributeNode()函数设置属性。 可以使用removeAttribute()删除属性。 这些函数有命名空间感知的等效项,即setAttributeNS(),setAttributeNodeNS()和removeAttributeNS())。
如果要访问节点的文本,请使用text(),例如
text()函数递归运算以查找文本(因为并非所有元素都包含文本)。 如果要查找所有节点的子节点中的所有文本,请迭代查找QDomText节点的子节点,例如,
QString text;
QDomElement element = doc.documentElement();
for(QDomNode n = element.firstChild(); !n.isNull(); n = n.nextSibling())
{
QDomText t = n.toText();
if (!t.isNull())
text += t.data();
}
请注意,我们尝试将每个节点转换为文本节点,并使用text()而不是直接在节点上使用firstChild()。toText()。data()或n.toText()。 不是一个文本元素。
您可以使用elementsByTagName()或elementsByTagNameNS()获取一个具有指定标签名称的元素的所有内容的列表。
要浏览dom文档的元素,请使用firstChildElement(),lastChildElement(),nextSiblingElement()和previousSiblingElement()。 例如,要遍历称为“数据库”的根元素中称为“条目”的所有子元素,可以使用:
QDomDocument doc = // ...
QDomElement root = doc.firstChildElement("database");
QDomElement elt = root.firstChildElement("entry");
for (; !elt.isNull(); elt = elt.nextSiblingElement("entry")) {
// ...
}
posted on 2017-05-02 09:12 965452300 阅读(1493) 评论(0) 编辑 收藏 举报