QDomDocument读取和编辑xml⽂件
Qt中⼏种操作xml的⽅式
流⽅式
sax⽅式
dom⽅式
初学时,我常常采⽤流⽅式读取xml,该⽅式简单直观,容易理解。之后遇到了需要修改xml并重新写回的情况,流⽅式就显得捉襟见肘了。
sax⽅式接触不多,从来没有在实际⽣产中使⽤过。
dom⽅式概念复杂,对于个⼈来说,⽂档也不是很清晰,导致我⼀直对这个⽅式不甚了解,最近下定决⼼好好研究⼀番,也算是⼤致清楚了个中“套路”,在此记录,以便今后查阅。
注意:如果你对QDomDocument没有任何了解,则不适合阅读此⽂章。如果你在使⽤QDomDocumentde的过程中产⽣了疑惑,则此⽂可能对你产⽣帮助。
如有疏漏,还望指正。
QDomNode ? QDomElemet? QDomAttr?QDomText?
初见QDomDocument时,我被这些东西搞得⼀头雾⽔。
直到我看到了某博客中这样⼀段话:
QDom前缀的都是代表节点类型。所以有,QDomElement代表⼀个Element节点,⽽QDomText代表⼀个Text节点。QDomNode 类可以存储任意类型的节点。如果想进⼀步处理⼀个节点,⾸先必须把它转化为正确的数据类型。QDomNode调⽤
toElement()以把它转化成QDomElement,然后调⽤tagName()来获得元素的标签名称。如果节点不是Element类型,那么toElement()函数就返回⼀个空QDomElement对象和⼀个空标签。
我们对xml操作,⽆⾮对节点⽂本,节点属性进⾏操作,因此,我着重在这个基础上整理⼀下。
QDomNode 兼容所有节点类型。
这⾥只讨论QDomNode为QDomElemet的情况;此时读者⼼⾥⼀惊,难道,还有不是的情况?当然有!
QDomNode QDomElemet
举个简单例⼦
你看!
有如下xml
<bookstore category="xml">
<book category="CHILDREN">
<title>Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<!-- asdasd-->
<book category="WEB">
<title>Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
<test>hello</test>
</bookstore>
有如下代码:
code 01
QDomElement root = doc.documentElement();
QDomNode node=  root.firstChild();
qDebug() << root.attributeNode("category").value();
while(!node.isNull())
{
qDebug() << "xx";
node = Sibling();
}
结果会输出⼏个xx呢?
代码做出如下更改
code 02
QDomElement root = doc.documentElement();
QDomElement node=  root.firstChildElement();
qDebug() << root.attributeNode("category").value();
while(!node.isNull())
{
qDebug() << "xx";
node = SiblingElement();
}
结果会输出⼏个xx呢?
答案分别是4和3!:smirk: :smirk:
结论:注释是QDomNode⽽不是QDomElement
到这⾥,⼤家应该就能明⽩两者的区别了。也应该能读懂上边的
QDomNode调⽤toElement()以把它转化成QDomElement,然后调⽤tagName()来获得元素的标签名称。如果节点不是Element类型,那么toElement()函数就返回⼀个空QDomElement对象和⼀个空标签
[========]
QDomElemet 与 QDomAttr QDomText
经过上⾯的试验,我们还可以得到另⼀个结论,那就是
属性不是QDomELement的⼦QDomELement
属性不是QDomNode的⼦QDomNode
还有⼀件事我们不知道,那就是QDomELement中的⽂本算是它的⼦QDomELement么?
<bookstore category="xml">hello</bookstore>
code 03
QDomElement ele=  root.firstChildElement();
while(!ele.isNull())
{
qDebug() << "xx";
ele = SiblingElement();
}
程序不会有任何输出
⽂本不是QDomELement的⼦QDomELement
code 04
QDomNode node=  root.firstChild();
while(!node.isNull())
spring怎么读取xml文件
{
qDebug() << "xx";
node = Sibling();
}
程序将会输出⼀个xx
⽂本是QDomNode的⼦QDomNode
了解了它们之间的联系之后,我们现在迫切的需要知道⼀个问题,既然⽂本和属性都不是⼦QDomELement,如何获取到⽂本和属性呢?读写xml
遍历某QDomELement的⼦QDomELement
⽰例xml
<bookstore category="xml">
<book category="CHILDREN">
<title>Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="WEB">
<title>Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
<test>hello</test>
</bookstore>
code 05 遍历
QDomDocument doc = QDomDocument();
QFile file("./l");
file.open(QFile::ReadWrite);
doc.setContent(&file);
QDomElement root = doc.documentElement();
QDomElement ele=  root.firstChildElement();
while(!ele.isNull())
{
/
/do something
ele = SiblingElement();
}
doc.documentElement()获取最顶级的QDomDocument,接下来的循环遍历了它所有的QDomDocument,对于它的⼦QDomDocument,同样可以使⽤以上⽅法。
如果⼀个QDomDocument的firstChildElement()返回的QDomElement为空(ele.isNull() 为 true),则说明他没有⼦QDomElement,也就意味着他是xml的最底层了,接下来介绍获取⽂本和属性的⽅法。
code 06 读取
QDomDocument doc = QDomDocument();
QFile file("./l");
file.open(QFile::ReadWrite);
doc.setContent(&file);
QDomElement root = doc.documentElement();
QDomElement ele=  root.firstChildElement();
qDebug() << root.attributeNode("category").nodeValue();
while(!ele.isNull())
{
//此处可以有多种判定⽅法,此处只是采⽤了⼦元素为空判定
//实际⽣产中你很可能不需要这样判断,根据xml结构直接判定元素名称即可
//如 if(ele.tagName() == "xxxx")
if(ele.firstChildElement().isNull())
{
qDebug() << ele.tagName();
qDebug() << ();
//⽂本是ele的⼦QDomNode,⽽不是ele本⾝!所以这样不会输出任何东西!
qDebug() << Text().nodeValue();
//如果真的需要转化为QDomText
QDomNode node = ele.firstChild();
while (!node.isNull()) {
if(node.isText())
{
qDebug() << Text().nodeValue();
}
node = Sibling();
}
}
ele = SiblingElement();
}
输出
"xml"
"test"
"hello"
""
"hello"
修改很简单,只需要将上边的nodeValue函数改为setNodeValue即可。记得要写回⽂件改动才会⽣效哦(详情请查看save⽅法的帮助⽂档)。除此之外QDomDocument还提供了替换节点的⽅法,⾃⾏探索。
转载请注明出处
<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" >

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。