实例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中type的构造函数参数含义说明
Jun 21 Python
python制作最美应用的爬虫
Oct 28 Python
Python简单实现控制电脑的方法
Jan 22 Python
python机器人行走步数问题的解决
Jan 29 Python
Python基础教程之利用期物处理并发
Mar 29 Python
Python后台开发Django会话控制的实现
Apr 15 Python
Python生命游戏实现原理及过程解析(附源代码)
Aug 01 Python
python matplotlib库绘制条形图练习题
Aug 10 Python
Python 实现自动导入缺失的库
Oct 29 Python
Windows 下更改 jupyterlab 默认启动位置的教程详解
May 18 Python
使用tensorflow实现VGG网络,训练mnist数据集方式
May 26 Python
Python中的特殊方法以及应用详解
Sep 20 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
MySQL时间字段究竟使用INT还是DateTime的说明
2012/02/27 PHP
PHP垃圾回收机制引用计数器概念分析
2013/06/24 PHP
windows下配置apache+php+mysql时出现问题的处理方法
2014/06/20 PHP
PHP使用pcntl_fork实现多进程下载图片的方法
2014/12/16 PHP
PHP使用curl制作简易百度搜索
2016/11/03 PHP
PHP判断数组是否为空的常用方法(五种方法)
2017/02/08 PHP
PHP框架Laravel中使用UUID实现数据分表操作示例
2018/05/30 PHP
JavaScript网页制作特殊效果用随机数
2007/05/22 Javascript
Javascript优化技巧(文件瘦身篇)
2008/01/28 Javascript
Javascript中的关键字和保留字整理
2014/10/16 Javascript
JavaScript中数据结构与算法(五):经典KMP算法
2015/06/19 Javascript
js实现横向伸展开的二级导航菜单代码
2015/08/28 Javascript
JavaScript获取IP获取的是IPV6 如何校验
2016/06/12 Javascript
vue实现简单表格组件实例详解
2017/04/16 Javascript
JavaScript实现焦点进入文本框内关闭输入法的核心代码
2017/09/20 Javascript
vue-resource拦截器设置头信息的实例
2017/10/27 Javascript
bootstrap 弹出框modal添加垂直方向滚轴效果
2018/07/09 Javascript
200行HTML+JavaScript实现年会抽奖程序
2019/01/22 Javascript
JS实现在线ps功能详解
2019/07/31 Javascript
基于JavaScript获取url参数2种方法
2020/04/17 Javascript
JavaScript 实现轮播图特效的示例
2020/11/05 Javascript
[36:20]完美世界DOTA2联赛PWL S3 access vs Rebirth 第一场 12.17
2020/12/18 DOTA
仅用500行Python代码实现一个英文解析器的教程
2015/04/02 Python
python实现自动发送报警监控邮件
2018/06/21 Python
Django ManyToManyField 跨越中间表查询的方法
2018/12/18 Python
python 画三维图像 曲面图和散点图的示例
2018/12/29 Python
Python使用while循环花式打印乘法表
2019/01/28 Python
Python实现播放和录制声音的功能
2020/08/12 Python
基于Django快速集成Echarts代码示例
2020/12/01 Python
新闻网站实习自我鉴定
2013/09/25 职场文书
门卫工作岗位职责
2013/12/17 职场文书
国际会议邀请函范文
2014/01/16 职场文书
应届毕业生应聘自荐信范文
2014/02/26 职场文书
《爱如茉莉》教后反思
2014/04/12 职场文书
解决Mysql多行子查询的使用及空值问题
2022/01/22 MySQL
JS中forEach()、map()、every()、some()和filter()的用法
2022/05/11 Javascript