实例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中使用SQLite的简单教程
Apr 29 Python
Python实现队列的方法
May 26 Python
深入理解Python中各种方法的运作原理
Jun 15 Python
Python使用设计模式中的责任链模式与迭代器模式的示例
Mar 02 Python
python语言使用技巧分享
May 31 Python
Python实现的手机号归属地相关信息查询功能示例
Jun 08 Python
python+openCV调用摄像头拍摄和处理图片的实现
Aug 06 Python
对Pytorch中Tensor的各种池化操作解析
Jan 03 Python
Python3基于print打印带颜色字符串
Jul 06 Python
python闭包与引用以及需要注意的陷阱
Sep 18 Python
python实现图片转字符画
Feb 19 Python
python实现计算图形面积
Feb 22 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 $_SERVER windows系统与linux系统下的区别说明
2014/02/14 PHP
利用PHP fsockopen 模拟POST/GET传送数据的方法
2015/09/22 PHP
CodeIgniter针对数据库的连接、配置及使用方法
2016/03/03 PHP
简单概括PHP的字符串中单引号与双引号的区别
2016/05/07 PHP
php关联数组与索引数组及其显示方法
2018/03/12 PHP
JavaScript 设计模式 富有表现力的Javascript(一)
2010/05/26 Javascript
自制基于jQuery的智能提示插件一枚
2011/02/18 Javascript
JavaScript中创建类/对象的几种方法总结
2013/11/29 Javascript
jquery append()方法与html()方法的区别及使用介绍
2014/08/01 Javascript
node.js中的fs.truncateSync方法使用说明
2014/12/15 Javascript
jqGrid表格应用之新增与删除数据附源码下载
2015/12/02 Javascript
jQuery时间验证和转换为标准格式的时间格式
2017/03/06 Javascript
Vue 父子组件、组件间通信
2017/03/08 Javascript
JS验证input输入框(字母,数字,符号,中文)
2017/03/23 Javascript
Require.js的基本用法详解
2017/07/03 Javascript
Vue0.1的过滤代码如何添加到Vue2.0直接使用
2017/08/23 Javascript
浅谈AngularJS中使用$resource(已更新)
2017/09/14 Javascript
微信小程序开发之好友列表字母列表跳转对应位置
2017/09/26 Javascript
JS扩展String.prototype.format字符串拼接的功能
2018/03/09 Javascript
vue中Axios的封装与API接口的管理详解
2018/08/09 Javascript
总结javascript三元运算符知识点
2018/09/28 Javascript
Vue实现简易翻页效果源码分享
2018/11/08 Javascript
node.js express框架简介与实现
2019/07/23 Javascript
[48:45]Ti4 循环赛第二日 NEWBEE vs EG
2014/07/11 DOTA
[23:21]Ti4 冒泡赛第二轮DK vs C9 2
2014/07/14 DOTA
在Python中使用next()方法操作文件的教程
2015/05/24 Python
Pytorch提取模型特征向量保存至csv的例子
2020/01/03 Python
使用Tensorflow实现可视化中间层和卷积层
2020/01/24 Python
使用IPython或Spyder将省略号表示的内容完整输出
2020/04/20 Python
css3加js做一个简单的3D行星运转效果实例代码
2017/01/18 HTML / CSS
浅谈HTML5中dialog元素尝鲜
2018/10/15 HTML / CSS
四风存在的原因分析
2014/02/11 职场文书
优秀员工演讲稿
2014/05/19 职场文书
道路施工安全责任书
2014/07/24 职场文书
活动费用申请报告
2015/05/15 职场文书
2016大学生党校学习心得体会
2016/01/06 职场文书