• Python处理XML


      在Python(以及其他编程语言)内有两种常见的方法处理XML:SAX(Simple API for XML)和DOM(Document Object Model,文档对象模型)。SAX语法分析器读取XML文件并且告知它发现的内容(文本,标签和特性)。由于它一次只村文档的一小部分,所以SAX简单,快速并能有效利用内存。DOM走的则是另外一条路:它构造一个表示整个文档的数据结构(文档树)。这样会慢些并且需要更多内存,但如果希望操作整个文档结构的话则很有用。

      Python内使用DOM的信息 http://docs.python.org/2/library/xml.dom.html 。除了标准的DOM处理外,标准库还包括另外两个模块:

    cml.dom.minidom(简化的DOM)和xml.dom.pulldom(SAX和DOM的结合体,减少了内存需求)。

      pyRXP(https://bitbucket.org/rptlab/pyrxp) 是个快速且简单的XML语法分析器(它并不使用DOM,但是会从XML文档中建立完整的文档树)。ElementTree (http://effbot.org/zone/elementtree.htm)则更加灵活易用。

      更多处理XML的Python工具请参看https://wiki.python.org/moin/PythonXml

      我们使用Python内置的SAX进行解析.

      SAX不用将整个文档加载到内存,基于事件驱动的API(Observer模式),用户只需要注册自己感兴趣的事件即可。在使用SAX进行解析时,有很多事件类型可用,但是这里只用到3个:元素的开始(开始标签的匹配项),元素的结束(关闭标签的匹配项)以及纯文本(字符)。要解析XML文件,可使用xml.sax模块的parse函数。这个函数负责读取文件并且生成时间——由于它要生成这3类事件,所以要调用一些事件处理程序。这些处理程序会作为内容处理程序(content handler)对象的方法来实现。需要继承 xml.sax.handler 中的 ContentHandler 类,因外它实现了所有需要的事件处理程序(只不过是没有任何效果的伪操作),可以在需要的时候覆盖这些函数。

      下面是一个xml文件 website.xml

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <website>
     3   <page name="index" title="Home Page">
     4     <h1>Welcome to My Home Page</h1>
     5     <p>
     6       Hi, there. My name is Mr. Gumby, and this is my home page. Here
     7       are some of my interests:
     8     </p>
     9     <ul>
    10       <li>
    11         <a href="interests/shouting.html">Shouting</a>
    12       </li>
    13       <li>
    14         <a href="interests/sleeping.html">Sleeping</a>
    15       </li>
    16       <li>
    17         <a href="interests/eating.html">Eating</a>
    18       </li>
    19     </ul>
    20   </page>
    21   <directory name="interests">
    22     <page name="shouting" title="Shouting">
    23       <h1>Mr. Gumby's Shouting Page</h1>
    24       <p>...</p>
    25     </page>
    26     <page name="sleeping" title="Sleeping">
    27       <h1>Mr. Gumby's Sleeping Page</h1>
    28       <p>...</p>
    29     </page>
    30     <page name="eating" title="Eating">
    31       <h1>Mr. Gumby's Eating Page</h1>
    32       <p>...</p>
    33     </page>
    34   </directory>
    35 </website>

          我们需要处理上述的xml文件,根据xml的内容可知,website.xml是一个网站系统的内容文件,我们根据其意思使用Python自动生成一个简易的网站系统。

      我们先用一个简单的例子演示如何使用Python SAX方式解析XML

    1 import os
    2 from xml.sax.handler import ContentHandler
    3 from xml.sax import parse
    4 
    5 class TestHandler(ContentHandler):
    6     def startElement(self, name, attrs):
    7         print name, attrs.keys()
    8 
    9 parse('website.xml', TestHandler())

      输出结果:

     1 website []
     2 page [u'name', u'title']
     3 h1 []
     4 p []
     5 ul []
     6 li []
     7 a [u'href']
     8 li []
     9 a [u'href']
    10 li []
    11 a [u'href']
    12 directory [u'name']
    13 page [u'name', u'title']
    14 h1 []
    15 p []
    16 page [u'name', u'title']
    17 h1 []
    18 p []
    19 page [u'name', u'title']
    20 h1 []
    21 p []

      使用SAX非常简单,如果我们对某个标签感兴趣,我们使用 if 语句进行判断然后进行相应的处理即可。

        我们现在编写一个完整的Python脚本对上面的XML进行处理:

      websit.xml

     1 from xml.sax.handler import ContentHandler
     2 from xml.sax import parse
     3 import os
     4 
     5 class Dispatcher(object):
     6 
     7     def dispatch(self, prefix, name, attrs=None):
     8         mname = prefix + name.capitalize()
     9         dname = 'default' + prefix.capitalize()
    10         method = getattr(self, mname, None)
    11         if callable(method):
    12             args = ()
    13         else:
    14             method = getattr(self, dname, None)
    15             args = name,
    16         if prefix == 'start':
    17             args += attrs,
    18         if callable(method):
    19             method(*args)
    20 
    21     def startElement(self, name, attrs):
    22         self.dispatch('start', name, attrs)
    23 
    24     def endElement(self, name):
    25         self.dispatch('end', name)
    26 
    27 class WebsiteConstructor(Dispatcher, ContentHandler):
    28 
    29     passthrough = False
    30 
    31     def __init__(self, directory):
    32         self.directory = [directory]
    33         self.ensureDirectory()
    34 
    35     def ensureDirectory(self):
    36         path = os.path.join(*self.directory)
    37         if not os.path.isdir(path):
    38             os.makedirs(path)
    39 
    40     def characters(self, content):
    41         if self.passthrough:
    42             self.out.write(content)
    43 
    44     def defaultStart(self, name, attrs):
    45         if self.passthrough:
    46             self.out.write('<' + name)
    47             for key, val in attrs.items():
    48                 self.out.write(' %s="%s"' % (key, val))
    49             self.out.write('>')
    50 
    51     def defaultEnd(self, name):
    52         if self.passthrough:
    53             self.out.write('</%s>' % name)
    54 
    55     def startDirectory(self, attrs):
    56         self.directory.append(attrs['name'])
    57         self.ensureDirectory()
    58 
    59     def endDirectory(self):
    60         self.directory.pop()
    61 
    62     def startPage(self, attrs):
    63         filename = os.path.join(*self.directory + [attrs['name'] + '.html'])
    64         self.out = open(filename, 'w')
    65         self.writeHeader(attrs['title'])
    66         self.passthrough = True
    67 
    68     def endPage(self):
    69         self.passthrough = False
    70         self.writeFooter()
    71         self.out.close()
    72 
    73     def writeHeader(self, title):
    74         self.out.write('<html>
     <head>
     <title>')
    75         self.out.write(title)
    76         self.out.write('</title>
     </head>
     <body>
    ')
    77 
    78     def writeFooter(self):
    79         self.out.write('
     </body>
    </html>
    ')
    80 
    81 XML = os.path.join('website.xml')
    82 parse(XML, WebsiteConstructor('public_html'))

      使用

    1 python website.py

      运行后我们会得到一堆HTML文件,文件内容即是xml文件定义的内容

      

  • 相关阅读:
    判断一个对象是否为空
    viewflipper的高度设置
    Android利用ViewFlipper实现屏幕切换动画效果
    锁屏状态下点亮屏幕,并弹出闹钟提示信息
    android如何取消闹铃
    luogu P1880(区间dp)
    luogu P2014 选课(树形dp)
    luogu P1122(树形dp)
    luogu P1352 (树形dp)
    luogu P1541 (dp)
  • 原文地址:https://www.cnblogs.com/ArtsCrafts/p/python_xml.html
Copyright © 2020-2023  润新知