XML文档的大略和易扩展属性使其可以很方便地在任何程序中读/写数据。 比如在QT开拓中,其常见的ui,qrc 后缀的文件都是一种XML格式的文档。QT供应类 QDomDocument来处理XML文档。
QDomDocment简介QDomDOcument类代表全体XML文档。从观点上讲,它是文档树的根,并供应对文档的访问。由于元素(elment), 文本节点(text node), 注释(comment),处理指令(processing instruction)等都包含在XML文档内,因此QDomDocument类中也包含了创建这里工具的函数。QDomDocument创建的节点工具都具有ownerDocument()函数,该函数将它们与其高下文(context)中创建的文档干系联。
解析后的XML文档在内部由工具数来表示,可以利用各种QDom类访问这些工具。所有的QDom类仅引用内部树中的工具。一旦引用它们的末了一个QDom工具或者QDomDocument本身被删除时,DOM树中的内部工具将被删除。

把稳:如果XML文档很大时,则Dom数可能会占用大量内存,在这种情形下,建议利用QXmlStreamreader或QXmlQuery类来处理这类XML文档。
利用QDom类常日按如下办法利用:
doc = QDomDocument('mydoc')file = QFile('mydoc.xml')if not file.open(QIOdevice.Readonly): returnif not doc.setContent(file): file.close() returnfile.close()#打印最外层元素的直接联系的子元素的所有元素的名称docElem = doc.documentElement()node = docElem.firstChild()while not node.isNull(): elem = node.toElement() #考试测验将节点转换成元素 if no elem.isNull(): print(elem.tagName() node = node.nextSibling()#在文档的末端添加一个新元素elem = doc.createElement('img')elem.setAttribute('src', 'myimage.png')docElem.appendChild(elem)
下面的代码利用DOM创建XML文档:
doc = QDomDocument('myXML')root = doc.createElement('myXML')doc.appendChild(root)tag = doc.createElement('Greeting')root.appendChild(tag)txt = doc.createTextNode('Hello World')tag.appendChild(txt)xml = doc.toString()
QDocument常用函数:
toString(self): 将已解析的文档转回其文本表示办法。setContent(self, ...): 将指定的文本设置为XML文档内容,函数会考试测验检测XML规范哀求的文档编码。nodeType(self): 返回DocumentNode。documentElement(self): 返回文档的根元素。elementById(self, elementId): 返回其ID即是elementId的元素。如果未找到具有ID的元素,则此函数返回None。elementsByTagName(self, tagname): 返回一个QDomNodeList,个中包含名称为tagname的文档中的所有元素。节点列表的顺序是在元素树的预遍历中碰着它们的顺序。createElement(self, tagname): 创建一个名为tagname的新元素,可以将其插入DOM树。createTextNode(self, value): 为可插入文档树的字符串value创建文本节点。createComment(self, value): 为插入文档中的字符串value创建新注释。createAttribute(self, name): 创建一个名为name的新属性,可以将其插入元素属性中。QDOM的一些常用类除了QDomDocument以外,还有一些常常利用的DOM类:
QDomNode: DOM树中所有节点的基类。QDomElement: 表示DOM树中的一个元素。QDomText: 表示已解析的XML文档中的文本数据。QXmlStreamReader: 供应了一个快速解析器,用于通过大略的流API读取格式精确的XML。QXmlQuery: 编译并实行以XQuery措辞编写的查询。QXmlQuery常日用于查询XML数据,但它也可以查询已建模为XML的非XML数据。测试利用QTreeView按树的办法来显示QDomDocument解析的XML文件,完全代码如下:
importsysfromPyQt5importQtCore,QtGui,QtWidgetsfromPyQt5.QtCoreimportQt,QFile,QIODevice,QModelIndex,QAbstractItemModelfromPyQt5.QtWidgetsimport(QApplication,QMainWindow,QMenuBar,QMenu,QAction,QFileDialog,QTreeView)fromPyQt5.QtXmlimportQDomDocumentclassDomItem(object):def__init__(self,node,row,parent=None):self.domNode=node#记录条款在其父条款中的位置self.rowNumber=rowself.parentItem=parentself.childItems={}defnode(self):returnself.domNodedefparent(self):returnself.parentItemdefchild(self,i):ifiinself.childItems:returnself.childItems[i]ifi>=0andi<self.domNode.childNodes().count():childNode=self.domNode.childNodes().item(i)childItem=DomItem(childNode,i,self)self.childItems[i]=childItemreturnchildItemreturnNonedefrow(self):returnself.rowNumberclassDomModel(QAbstractItemModel):def__init__(self,doucment,parent=None):super(DomModel,self).__init__(parent)self.domDocument=doucmentself.rootItem=DomItem(self.domDocument,0)#列数defcolumnCount(self,parent):return3#设置数据defdata(self,index,role):ifnotindex.isValid():returnNoneifrole!=Qt.DisplayRole:returnNoneitem=index.internalPointer()node=item.node()attributes=[]attributeMap=node.attributes()ifindex.column()==0:returnnode.nodeName()elifindex.column()==1:foriinrange(0,attributeMap.count()):attribute=attributeMap.item(i)attributes.append(attribute.nodeName()+'="'+attribute.nodeValue()+'"')return''.join(attributes)elifindex.column()==2:value=node.nodeValue()ifvalueisNone:return''return''.join(node.nodeValue().split('\n'))returnNonedefflags(self,index):ifnotindex.isValid():returnQt.NoItemFlagsreturnQt.ItemIsEnabled|Qt.ItemIsSelectable#设置表头各部分的标题信息defheaderData(self,section,orientation,role):iforientation==Qt.Horizontalandrole==Qt.DisplayRole:ifsection==0:return'名字'ifsection==1:return'属性'ifsection==2:return'值'returnNone#索引defindex(self,row,column,parent):ifnotself.hasIndex(row,column,parent):returnQModelIndex()ifnotparent.isValid():parentItem=self.rootItemelse:parentItem=parent.internalPointer()childItem=parentItem.child(row)ifchildItem:returnself.createIndex(row,column,childItem)else:returnQModelIndex()#父项defparent(self,child):ifnotchild.isValid():returnQModelIndex()childItem=child.internalPointer()parentItem=childItem.parent()ifnotparentItemorparentItem==self.rootItem:returnQModelIndex()returnself.createIndex(parentItem.row(),0,parentItem)#行数defrowCount(self,parent):ifparent.column()>0:return0ifnotparent.isValid():parentItem=self.rootItemelse:parentItem=parent.internalPointer()returnparentItem.node().childNodes().count()classDemoDomDocument(QMainWindow):def__init__(self,parent=None):super(DemoDomDocument,self).__init__(parent)#设置窗口标题self.setWindowTitle('实战QtforPython:XML文档处理演示')#设置窗口大小self.resize(480,360)self.initUi()definitUi(self):self.initMenuBar()self.xmlPath=''self.model=DomModel(QDomDocument(),self)self.view=QTreeView(self)self.view.setModel(self.model)self.setCentralWidget(self.view)definitMenuBar(self):menuBar=self.menuBar()menuFile=menuBar.addMenu('文件(&F)')menuFile.addAction('打开文件(&F)...',self.openFile,'Ctrl+O')menuFile.addAction('退出(&X)',QApplication.instance().quit,'Ctrl+Q')defopenFile(self):path,_=QFileDialog.getOpenFileName(self,'OpenFile',self.xmlPath,'XMLfiles(.xml);;HTMLfiles(.html);;''SVGfiles(.svg);;UserInterfacefiles(.ui)')ifpath:f=QFile(path)iff.open(QIODevice.ReadOnly):document=QDomDocument()ifdocument.setContent(f):newModel=DomModel(document,self)self.view.setModel(newModel)self.model=newModelself.xmlPath=pathf.close()if__name__=='__main__':app=QApplication(sys.argv)window=DemoDomDocument()window.show()sys.exit(app.exec())
运行结果如下图:
利用QDomDocument解析XML文件
本文知识点QDomDocument代表全体XML文档。利用QDomDocument解析XML文档。利用QTreeView显示XML。前一篇: 实战PyQt5: 126-利用QFile进行文件操作
请多多关注,评论,收藏,点赞,和转发。