实例Python处理XML文件的方法
admin
2023-07-31 02:35:24
0

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

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

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

上游读取到对应的数据

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

XML文件




id

query
varchar(200)
false
query

pv
integer
false
pv

avg_money
integer
false

处理脚本

#!/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文档



  100000
  
  
北京,海淀区
437 1989 333 242 null 大学 1 2月14日

处理
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()

相关内容

热门资讯

Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
定时清理删除C:\Progra... C:\Program Files (x86)下面很多scoped_dir开头的文件夹 写个批处理 定...
scoped_dir32_70... 一台虚拟机C盘总是莫名奇妙的空间用完,导致很多软件没法再运行。经过仔细检查发现是C:\Program...
500 行 Python 代码... 语法分析器描述了一个句子的语法结构,用来帮助其他的应用进行推理。自然语言引入了很多意外的歧义,以我们...
小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...
65536是2的几次方 计算2... 65536是2的16次方:65536=2⁶ 65536是256的2次方:65536=256 6553...
Apache Doris 2.... 亲爱的社区小伙伴们,我们很高兴地向大家宣布,Apache Doris 2.0.0 版本已于...
项目管理和工程管理的区别 项目管理 项目管理,顾名思义就是专注于开发和完成项目的管理,以实现目标并满足成功标准和项目要求。 工...