实例Python处理XML文件的方法


Posted in Python onAugust 31, 2015

需求
有一个表,里面数据量比较大,每天一更新,其字段可以通过xml配置文件进行配置,即,可能每次建表的字段不一样。

上游跑时会根据配置从源文件中提取,到入库这一步需要根据配置进行建表。

解决
写了一个简单的xml,配置需要字段及类型

上游读取到对应的数据

入库这一步,先把原表删除,根据配置建新表

XML文件

<?xml version="1.0" encoding="UTF-8"?>
<!-- 表名 ,数据库名  可灵活配置插入哪个库哪个表 -->
<table name="top_query" db_name="evaluting_sys">
<!-- 非业务主键,自增长,可配名,其他 INTEGER UNSIGNED AUTO_INCREMENT -->
<primary_key>
<name>id</name>
</primary_key>
<!-- 字段开始 -->
<field>
<name>query</name>
<type>varchar(200)</type>
<is_index>false</is_index>
<description>query</description>
</field>
<field>
<name>pv</name>
<type>integer</type>
<is_index>false</is_index>
<description>pv</description>
</field>
<field>
<name>avg_money</name>
<type>integer</type>
<is_index>false</is_index>
<description></description>
</field>
<!-- 字段配置结束 -->
</table>

处理脚本

#!/usr/bin/python
# -*- coding:utf-8 -*-
#author: wklken
#desc: use to read db xml config.
#-----------------------
#2012-02-18 created
#----------------------

import sys,os
from xml.dom import minidom, Node

def read_dbconfig_xml(xml_file_path):
  content = {}

  root = minidom.parse(xml_file_path)
  table = root.getElementsByTagName("table")[0]

  #read dbname and table name.
  table_name = table.getAttribute("name")
  db_name = table.getAttribute("db_name")

  if len(table_name) > 0 and len(db_name) > 0:
    db_sql = "create database if not exists `" + db_name +"`; use " + db_name + ";"
    table_drop_sql = "drop " + table_name + " if exists " + table_name + ";"
    content.update({"db_sql" : db_sql})
    content.update({"table_sql" : table_drop_sql })
  else:
    print "Error:attribute is not define well! db_name=" + db_name + " ;table_name=" + table_name
    sys.exit(1)
  #print table_name, db_name

  table_create_sql = "create table " + table_name +"("

  #read primary cell
  primary_key = table.getElementsByTagName("primary_key")[0]
  primary_key_name = primary_key.getElementsByTagName("name")[0].childNodes[0].nodeValue

  table_create_sql += primary_key_name + " INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,"

  #print primary_key.toxml()
  #read ordernary field
  fields = table.getElementsByTagName("field")
  f_index = 0
  for field in fields:
    f_index += 1
    name = field.getElementsByTagName("name")[0].childNodes[0].nodeValue
    type = field.getElementsByTagName("type")[0].childNodes[0].nodeValue
    table_create_sql += name + " " + type
    if f_index != len(fields):
    table_create_sql += ","
    is_index = field.getElementsByTagName("is_index")[0].childNodes[0].nodeValue

  table_create_sql += ");"
  content.update({"table_create_sql" : table_create_sql})
  #character set latin1 collate latin1_danish_ci;
  print content


if __name__ == "__main__":
read_dbconfig_xml(sys.argv[1])

PYTHON解析XML大文件[SAX]
需求
读取xml数据文件,文件较大,需要实时处理插入到数据库

xml文档

<PERSONS>
<person>
  <id>100000</id>
  <sex>男</sex>
  <address>北京,海淀区</address>
  <fansNum>437</fansNum>
  <summary>1989</summary>
  <wbNum>333</wbNum>
  <gzNum>242</gzNum>
  <blog>null</blog>
  <edu>大学</edu>
  <work></work>
  <renZh>1</renZh>
  <brithday>2月14日</brithday>
</person>
</PERSONS>

处理
sax处理时并不会像dom一样可以以类似节点的维度进行读取,它只有 开始标签 内容 结束标签 之分

处理思想是:通过一个handler,对开始标签,内容,结束标签各有一个处理函数

代码及注解
person 处理类

from xml.sax import handler,parseString
class PersonHandler(handler.ContentHandler):
 def __init__(self, db_ops):
  #db op obj
  self.db_ops = db_ops
  #存储一个person的map
  self.person = {}
  #当前的tag
  self.current_tag = ""
  #是否是tag之间的内容 ,目的拿到tag间内容,不受空白的干扰
  self.in_quote = 0
 #开始,清空map
 def startElement(self, name, attr):
  #以person,清空map
  if name == "person":
   self.person = {}
  #记录 状态
  self.current_tag = name
  self.in_quote = 1
 #结束,插入数据库
 def endElement(self, name):
  #以person结尾 代表读取一个person的信息结束
  if name == "person":
   #do something
   in_fields = tuple([ ('"' + self.person.get(i,"") + '"') for i in fields ])
   print in_sql % in_fields
   db_ops.insert( in_sql%(in_fields))
  #处理
  self.in_quote = 0
 def characters(self, content):
  #若是在tag之间的内容,更新到map中
  if self.in_quote:
   self.person.update({self.current_tag: content})

加上入库的完整代码

#!/usr/bin/python
# -*- coding:utf-8 -*-
#parse_person.py
#version : 0.1
#author : wukunliang@163.com
#desc : parse person.xml and out sql



import sys,os
import MySQLdb

reload(sys)
sys.setdefaultencoding('utf-8')

in_sql = "insert into person(id,sex,address,fansNum,summary,wbNum,gzNum,blog,edu,work,renZh,brithday) values(%s, %s, %s, %s, %s, %s,
     %s, %s, %s, %s, %s, %s)"

fields = ("id","sex","address","fansNum","summary","wbNum","gzNum","blog","edu","work","renZh","brithday")

#数据库方法
class Db_Connect:
  def __init__(self, db_host, user, pwd, db_name, charset="utf8", use_unicode = True):
    print "init begin"
    print db_host, user, pwd, db_name, charset , use_unicode
    self.conn = MySQLdb.Connection(db_host, user, pwd, db_name, charset=charset , use_unicode=use_unicode)
    print "init end"

  def insert(self, sql):
    try:
      n = self.conn.cursor().execute(sql)
      return n
    except MySQLdb.Warning, e:
      print "Error: execute sql '",sql,"' failed"

  def close(self):
    self.conn.close()

#person 处理类
from xml.sax import handler,parseString
class PersonHandler(handler.ContentHandler):
  def __init__(self, db_ops):
    #db op obj
    self.db_ops = db_ops
    #存储一个person的map
    self.person = {}
    #当前的tag
    self.current_tag = ""
    #是否是tag之间的内容
    self.in_quote = 0
  #开始,清空map
  def startElement(self, name, attr):
    #以person,清空map
    if name == "person":
     self.person = {}
    #记录 状态
    self.current_tag = name
    self.in_quote = 1
  #结束,插入数据库
  def endElement(self, name):
    #以person结尾 代表读取一个person的信息结束
    if name == "person":
      #do something
      in_fields = tuple([ ('"' + self.person.get(i,"") + '"') for i in fields ])
      print in_sql % in_fields
      db_ops.insert( in_sql%(in_fields))
    #处理
    self.in_quote = 0
  def characters(self, content):
    #若是在tag之间的内容,更新到map中
    if self.in_quote:
      self.person.update({self.current_tag: content})

if __name__ == "__main__":
  f = open("./person.xml")
  #如果源文件gbk 转码   若是utf-8,去掉decode.encode
  db_ops = Db_Connect("127.0.0.1", "root", "root", "test")
  parseString(f.read().decode("gbk").encode("utf-8"), PersonHandler(db_ops))
  f.close()
  db_ops.close()
Python 相关文章推荐
python多线程编程中的join函数使用心得
Sep 02 Python
python实现调用其他python脚本的方法
Oct 05 Python
Python OS模块常用函数说明
May 23 Python
浅谈pandas中Dataframe的查询方法([], loc, iloc, at, iat, ix)
Apr 10 Python
django 发送手机验证码的示例代码
Apr 25 Python
python3爬虫之设计签名小程序
Jun 19 Python
python 找出list中最大或者最小几个数的索引方法
Oct 30 Python
Python3 filecmp模块测试比较文件原理解析
Mar 23 Python
python字典的值可以修改吗
Jun 29 Python
python将字典内容写入json文件的实例代码
Aug 12 Python
pycharm 使用tab跳出正在编辑的括号(){}{}等问题
Feb 26 Python
秀!学妹看见都惊呆的Python小招数!【详细语言特性使用技巧】
Apr 27 Python
通过实例浅析Python对比C语言的编程思想差异
Aug 30 #Python
使用Python脚本将文字转换为图片的实例分享
Aug 29 #Python
Python中常见的数据类型小结
Aug 29 #Python
深入解析Python中的lambda表达式的用法
Aug 28 #Python
两个使用Python脚本操作文件的小示例分享
Aug 27 #Python
简介二分查找算法与相关的Python实现示例
Aug 26 #Python
使用Python的Bottle框架写一个简单的服务接口的示例
Aug 25 #Python
You might like
PHP仿博客园 个人博客(1) 数据库与界面设计
2013/07/05 PHP
ThinkPHP3.1的Widget新用法
2014/06/19 PHP
php视频拍照上传头像功能实现代码分享
2015/10/08 PHP
PHP入门教程之会话控制技巧(cookie与session)
2016/09/11 PHP
[原创]PHP实现生成vcf vcard文件功能类定义与使用方法详解【附demo源码下载】
2017/09/02 PHP
在laravel框架中实现封装公共方法全局调用
2019/10/14 PHP
javascript 常用代码技巧大收集
2009/02/25 Javascript
用Javascript 获取页面元素的位置的代码
2009/09/25 Javascript
JavaScript经典效果集锦
2010/07/06 Javascript
getComputedStyle与currentStyle获取样式(style/class)
2013/03/19 Javascript
判断一个变量是数组Array类型的方法
2013/09/16 Javascript
easyui datagrid 键盘上下控制选中行示例
2014/03/31 Javascript
Javascript中的apply()方法浅析
2015/03/15 Javascript
图解JavaScript中的this关键字
2020/05/28 Javascript
js实现漫天星星效果
2017/01/19 Javascript
canvas绘制万花筒效果(代码分享)
2017/01/20 Javascript
关于Stream和Buffer的相互转换详解
2017/07/26 Javascript
vue 动态改变静态图片以及请求网络图片的实现方法
2018/02/07 Javascript
解决vue脚手架项目打包后路由视图不显示的问题
2018/09/20 Javascript
js实现动态添加上传文件页面
2018/10/22 Javascript
vue中使用props传值的方法
2019/05/08 Javascript
简单谈谈python中的语句和语法
2017/08/10 Python
Python中类的初始化特殊方法
2017/12/01 Python
Python实现的生成格雷码功能示例
2018/01/24 Python
python读取和保存视频文件
2018/04/16 Python
JetBrains PyCharm(Community版本)的下载、安装和初步使用图文教程详解
2020/03/19 Python
如何在scrapy中捕获并处理各种异常
2020/09/28 Python
美国排名第一的泳池用品直接来源:In The Swim
2019/09/23 全球购物
Watch Station官方网站:世界一流的手表和智能手表
2020/01/05 全球购物
军训学生自我鉴定
2014/02/12 职场文书
解除劳动合同协议书
2014/04/14 职场文书
公司会议策划方案
2014/05/17 职场文书
法人代表身份证明书及授权委托书
2014/09/16 职场文书
警示教育片观后感
2015/06/17 职场文书
巴黎圣母院读书笔记
2015/06/26 职场文书
2015年高三毕业班班主任工作总结
2015/10/22 职场文书