尽管北方的春天比南方要晚很多,尽管这里经历两次气温骤降,尽管过程起伏跌宕,但是春天的脚步不会有丝毫地停顿,阵阵花香终会飘入房中。
该来的总会来的。
/doge
没啥,就是感慨一下苦等许久的春天终于来了而已。
昨天介绍了JSON格式文件的建立与读写,今天来讲另一种格式的文件:
在了解XML文件之前,我们首先来看一下这个表格:
这是一个非常简单的任务表,现在我们想要用程序把它记录下来,可是用昨天的类似键值对的JSON格式保存的话,一对一对的方式明显是不能满足我们的要求的,更不用说txt文件保存了。
所以,这个时候,我们就需要用到一种新的方式来保存。
XML格式是一种标记语言,它定义了一种保存数据的规则,使得机器与人类都可读。用XML格式保存如上列表的方式如下:
上图是直接打开了一个xml文件后显示的样子。
下图则是用电子表格打开xml文件的样子:
在了解了XML会以什么形式显示后,我们再来看一下它的结构。
昨天讲JSON文件的时候,是按照三个步骤进行的:1.写函数 2.读函数 3.主函数
今天我们在昨天的基础上拓展一下:把生成文件与写操作封装到一个类里面。
class New_XML(): #自定义建立XML文件类
def __init__(self,file = None):
self.file = file #自定义属性file
self.__get = None #自定义内部专用属性
我们定义了一个 file ,作为这个XML类的参数。而__get 是这个类内部使用的属性,会在随后的内容里用到
def open_X(self): #自定义打开XML文件函数
if self.file == None:
print('请输入一个文件!') #检测是否输入文件
return False
try:
self.__get = open(self.file,'a',encoding='utf-8')
#encoding='utf-8'是为了让输入的中文可供后续读取
#在不写时默认为 None————ASCII码
#类似昨天写JSON文件时的 ensure_ascii默认为 True时仅接受ASCII码
#等于False时可以接受汉字
except:
print('%s打开出错'%(self.file)) #异常处理
return False
encoding='utf-8’的解释在程序里的注释已经写得很清楚了,就不多说了。
def write_X(self,n,ele): #ele是元素的缩写
try:
if n == 0: #写入根元素
self.__get.write(ele+'\n')
else: #写入子元素
self.__get.write(''*n+ele+'\n')
except:
print('%s写入%s出错'%(self.file,ele)) #异常处理
def close_X(self): #关闭文件函数
if self.__get: #正常关闭文件
self.__get.close()
在写程序的时候要严格保证格式的正确,否则生成的XML文件无法正常打开,或者后续的解析会报错,就很闹心:)
content={1:[0,'' ], #日期
2:[4,'' ], #任务1开始
3:[8,'Math'], #数学
4:[8,'2 '], #学习时间
5:[8,'1 '], #练习时间
6:[4,''], #任务1结束
7:[4,'' ], #任务2开始
8:[8,'English'], #英语
9:[8,'2 '], #学习时间
10:[8,'1.5 '], #练习时间
11:[4,''], #任务2结束
12:[0,'']
}
在程序中,“0”,“4”,“8”分别代表了缩进的格数,如图:
file_test = r'f:\Python_Le\New.xml' #文件名称
flag = False #标志位
try:
New3.open_X()
for get in content.items():#字典转元组
New3.write_X(get[1][0],get[1][1])#把元组的第一个和第二个元素写入
flag = True
except:
print('写入文件出错')
finally:
if flag:
New3.close_X()
print('OK')
else:
print('over')
建立完文件不是就意味着结束了,还要对他进行各种操作。这时候就需要用到Python自带的xml模块。
xml模块包含两个最基本的API接口,SAX和DOM。(API:应用程序编程接口,是一些预先定义的函数,)
与SAX不同的是,DOM允许更改XML文件。二者在功能上互相补充。DOM就不在此文细说了,以后如果有机会的话再说。
用SAX解析XML文档有两个部分:解析器和事件处理器
解析器:读取XML文件,并向时间处理器发送事件,如元素开始与元素结束等。
事件处理器:对解析器传来的时间做出响应,由ContentHandler类实现
我们在模块里找到这个类,发现其提供了各种方法,
如:startElement、endElement、characters等等等等,这些会在稍后的程序里写明。
ContentHandler类用于处理解析器传来的事件。但是为了适用于我们自己的xml文件,我们应稍微改造一下这个类。
import xml.sax
class MyMission(xml.sax.ContentHandler): #继承ContentHandler父类
def __init__(self):#初始化
self.CurrentData=""#中间量
self.task="" #工作
self.sub ="" #科目
self.S_hour="" #学习时间
self.T_hour="" #练习时间
def startElement(self,label,att): #元素开始事件 label:标签 att:属性
self.CurrentData = label
if label=="task":
time = att["time"]
print(time)
task为开始的标签
def endElement(self,label): #元素结束事件
if self.CurrentData=="sub":
print("sub:"+self.sub)
elif self.CurrentData=="S_hour":
print("S_hour:"+self.S_hour)
elif self.CurrentData=="T_hour":
print("T_hour:"+self.T_hour)
self.CurrentData=""
在打印了task以后,在这里分别打印sub,S与T。
这里的print只是为了演示,也可以在最初定义一个列表,然后在这里把各个元素都添加到列表里,最后打印列表等等等等操作。(记得用global声明全局变量)
def characters(self,content): #content:对应元素里的内容
if self.CurrentData=="sub":
self.sub=content
elif self.CurrentData=="S_hour":
self.S_hour=content
elif self.CurrentData=="T_hour":
self.T_hour=content
这个类就算是继承完了/doge,现在它已经具备了基本的解析xml文件的功能。
file_test = r'f:\Python_Le\New.xml' #文件名称
parser=xml.sax.make_parser() #创建一个解析器的XMLReader对象
parser.setFeature(xml.sax.handler.feature_namespaces,0)#关闭解析命令空间
Handler = MyMission() #实例化
parser.setContentHandler(Handler) #为解析器建立时间处理实例
parser.parse(file_test) #解析指定XML文件
其中用到的make_parser()等均是在xml.sax下的函数,感兴趣的话可以自己在模块中查看源码以及用法/doge
F5运行:
再次强调一遍,一定要严格检查自己写的XML的格式是否正确以及是否前后一致,今凌晨现写的程序,怎么执行都报错,一遍遍检查也没看出来哪里写错了:)
后来太困了就睡觉了。早晨醒来,仔细想了想,觉得可能是创建的xml文件有问题,一看果然:)
果然不能半夜写程序,半夜脑袋混:(
该来的总会来的/doge
这个Python的基础系列到此就算是结束了。但是,学习永无止境,旧的结束也意味着新的开始。Python不会停,但不会再使用这个“第n天”的主题,而是以某某应用的形式陆续发布,目前计划在下周开启新的短篇系列,敬请期待/doge
——————
算上第零期,这个系列正好更新了25天,总算是凑了个还算整的数= =
其实25天前,自己压根就没觉得能坚持下来,毕竟又要上课还有考试还要云调车还要锻炼身体还要复习(高数[,线代[,概率论]])英语等等等等事情,讲道理,作为一个普通的学生,我是真的不明白该如何去合理分配一天的时间QAQ,总感觉24小时不够用= =
可能这就是眼高手低吧
可能这就是我学不过学霸的原因吧
不过,不光这个Python基础系列更完了,我甚至还在五一假期加更了一个3天让车跑起来的系列。其实这个3天跑车只是临时起意,没想到我真的完成它了233333
——————
新人初来乍到,第一次写系列文。无论是在python方面,还是在排版与写文方面,我都只是个菜鸟(这一点可以从这么长这么啰嗦的后话里看出来啊哈哈)如果有大佬惠临我这个小白留下的笔记,也请不要嫌弃我的低水平,就当是看个笑话,若是您愿意对我的文章提出宝贵的建议或者批评,我将不胜荣幸,并一定会吸取教训,深刻反思。