网站首页 > java教程 正文
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):
return
if not doc.setContent(file):
file.close()
return
file.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文件,完整代码如下:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt, QFile, QIODevice, QModelIndex, QAbstractItemModel
from PyQt5.QtWidgets import (QApplication, QMainWindow, QMenuBar, QMenu, QAction,
QFileDialog, QTreeView)
from PyQt5.QtXml import QDomDocument
class DomItem(object):
def __init__(self, node, row, parent=None):
self.domNode = node
#记录条目在其父条目中的位置
self.rowNumber = row
self.parentItem = parent
self.childItems = {}
def node(self):
return self.domNode
def parent(self):
return self.parentItem
def child(self, i):
if i in self.childItems:
return self.childItems[i]
if i >= 0 and i < self.domNode.childNodes().count():
childNode = self.domNode.childNodes().item(i)
childItem = DomItem(childNode, i, self)
self.childItems[i] = childItem
return childItem
return None
def row(self):
return self.rowNumber
class DomModel(QAbstractItemModel):
def __init__(self, doucment, parent=None):
super(DomModel, self).__init__(parent)
self.domDocument = doucment
self.rootItem = DomItem(self.domDocument, 0)
#列数
def columnCount(self, parent):
return 3
#设置数据
def data(self, index, role):
if not index.isValid():
return None
if role != Qt.DisplayRole:
return None
item = index.internalPointer()
node = item.node()
attributes = []
attributeMap = node.attributes()
if index.column() == 0:
return node.nodeName()
elif index.column() == 1:
for i in range(0, attributeMap.count()):
attribute = attributeMap.item(i)
attributes.append(attribute.nodeName() + '="' + attribute.nodeValue() + '"')
return ' '.join(attributes)
elif index.column() == 2:
value = node.nodeValue()
if value is None:
return ''
return ' '.join(node.nodeValue().split('\n'))
return None
def flags(self, index):
if not index.isValid():
return Qt.NoItemFlags
return Qt.ItemIsEnabled | Qt.ItemIsSelectable
#设置表头各部分的标题信息
def headerData(self, section, orientation, role):
if orientation == Qt.Horizontal and role == Qt.DisplayRole:
if section == 0:
return '名字'
if section == 1:
return '属性'
if section == 2:
return '值'
return None
#索引
def index(self, row, column, parent):
if not self.hasIndex(row, column, parent):
return QModelIndex()
if not parent.isValid():
parentItem = self.rootItem
else:
parentItem = parent.internalPointer()
childItem = parentItem.child(row)
if childItem:
return self.createIndex(row, column, childItem)
else:
return QModelIndex()
#父项
def parent(self, child):
if not child.isValid():
return QModelIndex()
childItem = child.internalPointer()
parentItem = childItem.parent()
if not parentItem or parentItem == self.rootItem:
return QModelIndex()
return self.createIndex(parentItem.row(), 0, parentItem)
#行数
def rowCount(self, parent):
if parent.column() > 0:
return 0
if not parent.isValid():
parentItem = self.rootItem
else:
parentItem = parent.internalPointer()
return parentItem.node().childNodes().count()
class DemoDomDocument(QMainWindow):
def __init__(self, parent=None):
super(DemoDomDocument, self).__init__(parent)
# 设置窗口标题
self.setWindowTitle('实战Qt for Python: XML文档处理演示')
# 设置窗口大小
self.resize(480, 360)
self.initUi()
def initUi(self):
self.initMenuBar()
self.xmlPath = ''
self.model = DomModel(QDomDocument(), self)
self.view = QTreeView(self)
self.view.setModel(self.model)
self.setCentralWidget(self.view)
def initMenuBar(self):
menuBar = self.menuBar()
menuFile = menuBar.addMenu('文件(&F)')
menuFile.addAction('打开文件(&F)...', self.openFile, 'Ctrl+O')
menuFile.addAction('退出(&X)', QApplication.instance().quit, 'Ctrl+Q')
def openFile(self):
path,_ = QFileDialog.getOpenFileName(self, 'OpenFile', self.xmlPath,
'XML files (*.xml);;HTML files (*.html);;'
'SVG files (*.svg);;User Interface files (*.ui)')
if path:
f = QFile(path)
if f.open(QIODevice.ReadOnly):
document = QDomDocument()
if document.setContent(f):
newModel = DomModel(document, self)
self.view.setModel(newModel)
self.model = newModel
self.xmlPath = path
f.close()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = DemoDomDocument()
window.show()
sys.exit(app.exec())
运行结果如下图:
本文知识点
- QDomDocument代表整个XML文档。
- 使用QDomDocument解析XML文档。
- 使用QTreeView显示XML。
前一篇: 实战PyQt5: 126-使用QFile进行文件操作
请多多关注,评论,收藏,点赞,和转发。
猜你喜欢
- 2024-11-10 Spring 基于 XML 的 IOC(spring xml map)
- 2024-11-10 阿里P7大神,Java学习之路-IO流与XML,超赞分享
- 2024-11-10 如何用Ajax解析json,XML数据格式
- 2024-11-10 Python和XML(python)
- 2024-11-10 Qt开发-流方法解析XML(qt读取文件流)
- 2024-11-10 Kettle(PDI)转换中输出之XML输出详解
- 2024-11-10 Java代码审计之不安全的Java代码(java安全点有哪些)
- 2024-11-10 spring boot Mybatis Mapper.xml使用总结
- 2024-11-10 Redis基本数据结构之字符串(redis的字符串类型是怎样实现的)
- 2024-11-10 Tomcat Server.xml配置详解(tomcat service配置)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)