DBLP是计算机领域内对研究的成果以作者为核心的一个计算机类英文文献的集成数据库系统,按年代列出了作者的科研成果。包括国际期刊和会议等公开发表的论文。DBLP没有提供对中文文献的收录和检索功能,国内类似的权威期刊及重要会议论文集成检索系统有C-DBLP。其并没有把数据保存在数据库中,而是保存在了XML文件中。DBLP在学术界声誉很高,而且很多论文及实验都是基于DBLP的。所收录的期刊和会议论文质量较高,也比较全面。能很好地反应了国外学术研究的前沿方向。DBLP数据下载地址
XML 指可扩展标记语言(eXtensible Markup Language),XML 被设计用来传输和存储数据。XML是一套定义语义标记的规则,这些标记将文档分成许多部件并对这些部件加以标识。它也是元标记语言,即定义了用于定义其他与特定领域有关的、语义的、结构化的标记语言的句法语言。
本文介绍了python三种常见的xml解析方法,分别是SAX,DOM,ElementTree。以DBLP的xml数据为例,用SAX的方式对xml数据进行解析,并对解析后的数据保存到了txt文件中。
python对XML的解析
常见的XML编程接口有DOM和SAX,这两种接口处理XML文件的方式不同,当然使用场合也不同。python有三种方法解析XML,SAX,DOM,以及ElementTree:
1.SAX (simple API for XML )
python 标准库包含SAX解析器,SAX用事件驱动模型,通过在解析XML的过程中触发一个个的事件并调用用户定义的回调函数来处理XML文件。
2.DOM(Document Object Model)
将XML数据在内存中解析成一个树,通过对树的操作来操作XML。
3.ElementTree(元素树)
ElementTree就像一个轻量级的DOM,具有方便友好的API。代码可用性好,速度快,消耗内存少。
PS:因DOM需要将XML数据映射到内存中的树,一是比较慢,二是比较耗内存,而SAX流式读取XML文件,比较快,占用内存少,但需要用户实现回调函数(handler)。
python 解析DBLP数据的方式
DBLP数据的格式如下图,红色框部分是数据集的某个完整属性。每份数据以属性article开头,子属性共有9个,分别是(author,title,pages,year,volume,journal,number,url,ee)。注意作者author这个属性可能不止一个,因为每篇论文的作者可以有多个。
代码,gogo帅提供:
# -*- coding: utf-8 -*-
"""
Created on Tue Jan 10 14:10:12 2017
@author: Administrator
"""
#!/usr/bin/python
# -*- coding: UTF-8 -*-
from __future__ import print_function
import xml.sax
import sys
import io
import traceback
sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='utf8') #改变标准输出的默认编码
class MovieHandler( xml.sax.ContentHandler ):
res=''
def __init__(self):
self.CurrentData = ""
self.author = ""
self.title = ""
self.pages = ""
self.year = ""
self.volume = ""
self.journal = ""
self.number = ""
self.url = ""
self.ee = ""
# 元素开始事件处理
def startElement(self, tag, attributes):
self.CurrentData = tag
if tag == "article":
print("self.__class__.res=",self.__class__.res)
try:
ww.write(self.__class__.res+'\n')//数据集中有不良数据,捕获一下
except:
traceback.print_exc()
self.__class__.res=''
# print ("*****article*****")
mdate = attributes["mdate"]
#print ("mdate:", mdate)
key=attributes["key"]
#print ("key:",key)
self.__class__.res=self.__class__.res+mdate+';,;'+key+';,;'
#print ('res_init:',self.__class__.res)
# 元素结束事件处理
def endElement(self, tag):
if self.CurrentData == "author":
#print ("author:", self.author)
self.__class__.res=self.__class__.res+self.author+';,;'
elif self.CurrentData == "title":
#print ("title:", self.title)
self.__class__.res=self.__class__.res+self.title+';,;'
elif self.CurrentData == "pages":
#print ("pages:", self.pages)
self.__class__.res=self.__class__.res+self.pages+';,;'
elif self.CurrentData == "year":
#print ("year:", self.year)
self.__class__.res=self.__class__.res+self.year+';,;'
elif self.CurrentData == "volume":
#print ("volume:", self.volume)
self.__class__.res=self.__class__.res+self.volume+';,;'
elif self.CurrentData == "journal":
#print ("journal:", self.journal)
self.__class__.res=self.__class__.res+self.journal+';,;'
elif self.CurrentData == "number":
#print ("number:", self.number)
self.__class__.res=self.__class__.res+self.number+';,;'
elif self.CurrentData == "url":
#print ("url:", self.url)
self.__class__.res=self.__class__.res+self.url+';,;'
elif self.CurrentData == "ee":
#print ("ee:", self.ee)
self.__class__.res=self.__class__.res+self.ee+';,;'
self.CurrentData = ""
# 内容事件处理
def characters(self, content):
if self.CurrentData == "author":
self.author = content+'####'
elif self.CurrentData == "title":
self.title = content
elif self.CurrentData == "pages":
self.pages = content
elif self.CurrentData == "year":
self.year = content
elif self.CurrentData == "volume":
self.volume = content
elif self.CurrentData == "journal":
self.journal = content
elif self.CurrentData == "number":
self.number = content
elif self.CurrentData == "url":
self.url = content
elif self.CurrentData == "ee":
self.ee = content
if ( __name__ == "__main__"):
parser = xml.sax.make_parser()
parser.setFeature(xml.sax.handler.feature_namespaces, 0)
Handler = MovieHandler()
parser.setContentHandler( Handler )
ww=open('dblp_parse_result.txt','w+')
parser.parse("dblp.xml")
ww.close()
注意:只需下载dblp.dtd和dblp.xml.gz两个文件,红色框圈住的,而且读取数据的时候,两个文件要放在同一个目录下面。
参考资料:http://www.runoob.com/python/python-xml.html