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);

 

QString xml = doc.toString();

 

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  详细说明

子类:QDomAttrQDomCharacterDataQDomDocumentQDomDocumentFragmentQDomDocumentTypeQDomElementQDomEntityQDomEntityReferenceQDomNotation, 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(),例如

QDomElement e = //...
//...
QString s = e.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  阅读(1315)  评论(0编辑  收藏  举报