Python解析xml与JSON

xml与json是常用的文件交换格式,常用来表示网页的html则是xml的变种。解析xml和json在web开发中有着重要应用。

DOM解析XML

文件对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展置标语言的标准编程接口。

DOM 的解析器在解析一个 XML 文档时,一次性读取整个文档,把文档中所有元素保存在内存中的一个树结构里,然后可以使用DOM API访问或修改xml。

xml示例:

<!-- movies.xml -->
<collection type="New Arrivals">
   <movie title="Enemy Behind">
      <stars>10</stars>
      <description>Talk about a US-Japan war</description>
   </movie>
   <movie title="Transformers">
      <stars>8</stars>
      <description>A schientific fiction</description>
   </movie>
</collection>

python中用xml.dom.minidom来解析xml:

import xml.dom.minidom

DOMTree = xml.dom.minidom.parse("movies.xml")
collection = DOMTree.documentElement
if collection.hasAttribute("shelf"):
   print("Root element : %s" % collection.getAttribute("type"))
# get attribute of an element

movies = collection.getElementsByTagName("movie")
# get child elements' collection by tag name    

for movie in movies:
   print("*****Movie*****")
   if movie.hasAttribute("title"):
      print "Title: %s" % movie.getAttribute("title")

   stars = movie.getElementsByTagName('stars')[0]
   print ("Stars: %s" % stars.childNodes[0].data)

   description = movie.getElementsByTagName('description')[0]
   print ("Description: %s" % description.childNodes[0].data)

SAX解析XML

SAX是一种基于事件驱动的xml解析器,SAX包括两个部分解析器和事件处理器。解析器负责读取xml文件并向事件处理器发送消息。事件处理器主要需要对三个事件进行处理:

  • startElement 元素开始事件,当读取元素头标签时触发

  • endElement 元素结束事件,当读取元素头标签时触发

  • characters 内容事件,当读取元素头标签与尾标签之间内容时触发

解析器由Python提供,事件处理器需要继承xml.sax.ContentHandler类并重写相应的事件处理函数:

import xml.sax

class MovieHandler( xml.sax.ContentHandler ):
    def __init__(self):
        self.currentTag = ""
        self.stars = ""
        self.description = ""
    
    def startElement(self, tag, attributes):
        # "tag" stands for the name of current tag
        # "attributes" is a dict of attributes of current tag  
        self.currentTag = tag 
        if tag == "movie" :
            print "*****Movie*****"
            title = attributes["title"]
            print "Title:", title
    #only parse tag <movie>, ignore other tags      

    def endElement(self, tag):
        if self.currentTag == "stars":
            print "Stars:", self.stars
        elif self.currentTag == "description":
            print "Description:", self.description
        self.currentTag = ""

    def characters(self, content):
        # "content" stands for the str between <tag> and </tag>
        if self.currentTag == "stars":
            self.stars = content
        elif self.currentTag == "description":
            self.description = content
      
if  __name__ == "__main__" :
       
    # create XMLReader
    parser = xml.sax.make_parser()
    
    # implement ContextHandler
    Handler = MovieHandler()
    parser.setContentHandler( Handler )
       
    parser.parse("movie.xml")

JSON解析

JSON(JavaScript Object Notation),是一种轻量级的数据交换格式。JSON 语法是 JavaScript 对象表示语法的子集:

  • 数据保存在键值对中
  • 键值对之间用","分隔
  • "{}"保存字典(JS中的对象)
  • "[]"保存列表(JS中的数组)

示例:

>>> import json
>>> obj = [True, False,None, 3.14, [1,2,3], {'name':'user'}];   
>>>> jsonString = json.dumps(obj)
>>> print(jsonString)
[true, false, null, 3.14, [1, 2, 3], {"name": "user"}]
>>> json.loads(jsonString)
[True, False, None, 3.14, [1, 2, 3], {u'name': u'user'}]

json.dumps方法提供了很多参数可供选择,比较常用的有sort_keys(对dict对象进行排序,默认dict是无序存放的),separators,indent等参数。

json模块只能对Python内置类型进行编码。若要使自定义类可以编码,需要自定义MyEncoder类继承json.JSONEncoder并重写default方法返回一个dict,其中的键值对将被添加到JSON中。

调用MyEncoder.encode(obj)方法,将会根据default方法的定义返回JSON字符串。

自定义MyDecoder类,并继承json.JSONDecoder。并在初始化JSONDecoder类时向object_hook参数传入一个可以将dict转换为类的方法对象。

Tips:

  • obj.__dict__是一个包含当前对象所有属性(不包括方法)的字典,无需手动添加属性。

  • 使用getattr(module,class_name)获得类(type对象)

示例:

import json

class Person(object):
    """docstring for Person"""
    def __init__(self, name, age):
        self.name = name
        self.age = age
 
class MyEncoder(json.JSONEncoder):
    def default(self,obj):
        #convert object to a dict
        d = {}
        d['__class__'] = obj.__class__.__name__
        d['__module__'] = obj.__module__
        d.update(obj.__dict__)
        return d
 
class MyDecoder(json.JSONDecoder):
    def __init__(self):
        json.JSONDecoder.__init__(self,object_hook=self.dict2object)

    def dict2object(self,d):
        #convert dict to object
        if '__class__' in d:
            class_name = d.pop('__class__')
            module_name = d.pop('__module__')
            module = __import__(module_name)
            class_ = getattr(module,class_name)
            args = dict((key.encode('ascii'), value) for key, value in d.items()) #get args
            inst = class_(**args) #create new instance
        else:
            inst = d
        return inst
 
p = Person('Peter',22)
d = MyEncoder().encode(p)
o =  MyDecoder().decode(d)
 
print d
print type(o), o
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值