python之xml文件处理的例子-问题描述及解决方法

本文介绍了在Python中处理XML文件,提取特定标签属性值并保存到Excel的过程。遇到的问题包括:中文编码错误、Excel中文乱码和文件生成后多一行空白。通过使用SAX或xml.dom解析XML,用csv模块写入Excel,以及调整编码方式解决了编码问题。对于Excel乱码,通过特定方法在Excel中显示正确。另外,还讨论了处理路径和遍历文件夹时需要注意的事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

待解决问题描述:

多个XML文件,具有相同的格式,如下:

<?xml version="1.0" encoding="UTF-8"?>
<test  name="F000 ">
…
</test>
<test  name="F001 ">
…
</test>
<test  name="F002 ">
…
</test>
…
不同xml文件中的<test>标签个数不同。有的50个,有的80个。

 

代码目标:

提取test 标签的 name 属性值,将这些值保存到excel文件中,并为每个值加上日期。生成表格如下:

F000

1月6日

F001

1月6日

F002

1月6日

1月6日


说明:每个xml文件会生成一个如上的表格。将所有这些表格保存到同一个excel文件中。

 

解决步骤:

1.      解析xml

方法一:使用python API SAX .

http://www.runoob.com/python/python-xml.html

 

方法二:使用xml.dom

Dom 方法将xml文件一次性读取,保存在一个树形结构中,读取文档内容很方便。

 

2.      csv module写excel文件

很多码友分享可以用csv模块处理,将提取的文件写入csv文件,excel会将csv格式转换成表格。

#!/usr/bin/python
# -*- coding: UTF-8 -*-
testname = [‘F000’,’F001’,’F002’]
import csv
#write to file
with open('report.csv', 'w') as csvfile:
    spamwriter = csv.writer(csvfile,dialect='excel')
    for item in testname:
       spamwriter.writerow(item)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
csvfile.close()

list 变量testname 保存目标字符串,将其存入到python 的list中。

然后import csv模块写入文件report.csv。

 

遇到的问题一:中文编码

参考的文章:

http://blog.youkuaiyun.com/andoring/article/details/6575183

http://www.crifan.com/summary_python_2_x_common_string_encode_decode_error_reason_and_solution/ 

 

当目标字符串中含有中文时,xml模块读入此字符串后,存为unicode。

用下面方法打印看看:

print isinstance(testname[1], unicode)

打印为True。

尽管在python文件的开头声明了编码方式:# -*- coding: UTF-8 -*- , 中文字符串依然以unicode编码保存。

有意思的是,testname变量是一个list, 它里面的元素被存为unicode, 但如果查看testname 这个list的编码方式,发现打印为False, 即它不是用unicode编码。

查阅python的帮助文档,摘下描述:

The csv module doesn’tdirectly support reading and writing Unicode, but it is 8-bit-clean save forsome problems with ASCII NUL characters. So you can write functions or classesthat handle the encoding and decoding for you as long as you avoid encodingslike UTF-16 that use NULs. UTF-8 is recommended.

说明csv module 不直接处理unicode格式。

这就是为什么调用spamwriter.writerow(item) 方法时报错UnicodeEncodeError的原因。

UnicodeEncodeError: 'ascii' codec can't encode characters in position 5-8: ordinal not in range(128)

使用str 的encode方法将unicode转换为UTF-8后运行成功。

spamwriter.writerow(item .encode('UTF-8'))

成功生成report.csv文件后,用MS office打开,新问题出现——中文乱码。

 

暂时没找到办法用代码解决,找到一条百度经验,试验有效:

http://jingyan.baidu.com/article/3c48dd3464b46ce10be3581f.html

 

遗留的问题:notepad中可以正常显示日期:2016/1/30

但如百度经验中操作后,用excel打开却显示: ######## 。在此单元格上双击则正常显示出日期。再换个单元格双击,整个列的日期都正常显示出来。奇怪~~

 

遇到的问题二:生成的excel文件中多一行空白。

参考的文章:

http://blog.youkuaiyun.com/pfm685757/article/details/47806469

我用的版本是python27, 写成如下就没有问题了。用‘wb’方式打开csv 文件。

with open('report.csv', 'wb') as csvfile:

 补充,由于是需要对多个xml文件处理,希望把不同文件中提取出的目标字符串保存到同一个文件中,因使用增量方式写文件,将'wb'改为'ab'

with open('report.csv', 'ab') as csvfile:


3. 用xlrd等excel处理工具。待学习。。。

 

4.  遍历文件 http://www.jb51.net/article/54640.htm

       遇到问题三:对路径的处理。

       由于路径中存在’\’, 直接把一个路径赋值给一个变量的时候,需要转义,即为c:\\mypath。要处理该路径下某个文件时,又需要使用其原始的,非转义的路径,即c:\mypath。 处理不当导致错误:

IOError: [Errno 2] No such file or directory: 'D:\\Python27\\works\\RFlogxml\\xmlst.xml'

os.path.join 处理路径,参考下面的文章:

http://blog.youkuaiyun.com/murphykwu/article/details/39785353

 

例如:在C:\TDDOWNLOAD目录下有a.txt、b.txt两个文件,另有\sub1子文件夹,C:\TDDOWNLOAD\sub1下又有c.txt、d.txt两个文件。

1. os.walk
os.walk()返回一个三元素的tuple:当前路径、子文件夹名称、文件列表。
>>> import os
>>> def fun( path ):
... for root, dirs, files in os.walk( path ):
... for fn in files:
... print root, fn
... 
>>> fun( r'C:\TDDOWNLOAD' )
C:\TDDOWNLOAD a.txt
C:\TDDOWNLOAD b.txt
C:\TDDOWNLOAD\sub1 c.txt
C:\TDDOWNLOAD\sub1 d.txt
>>> 

2. glob.glob
glob.glob()只接受一个参数,这个参数既代有路径,又代有匹配模式,返回值为一个列表。注意,glob.glob()无法直接穿透子文件夹,需要自己处理:
>>> def fun( path ):
... for fn in glob.glob( path + os.sep + '*' ): # '*'代表匹配所有文件
... if os.path.isdir( fn ): # 如果结果为文件夹
... fun( fn ) # 递归
... else:
... print fn
... 
>>> fun( r'C:\TDDOWNLOAD' )
C:\TDDOWNLOAD\a.txt
C:\TDDOWNLOAD\b.txt
C:\TDDOWNLOAD\sub1\c.txt
C:\TDDOWNLOAD\sub1\d.txt
>>> 

'*'为匹配模式,代表匹配所有文件,只有这样才能将子文件夹查出来,以便递归深入,探查下一层的文件。


参考如下文章的处理方式:

http://blog.youkuaiyun.com/murphykwu/article/details/39785353

**folderTravel.py

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import os
import xmlparserDOM  as parser
import re
#http://blog.youkuaiyun.com/murphykwu/article/details/39785353
 
rootdir = os.getcwd() 
print('rootdir = ' + rootdir) 
 
for (dirpath, dirnames, filenames) in os.walk(rootdir): 
    #print('dirpath = ' + dirpath) 
    for dirname in dirnames: 
        print('dirname = ' + dirname) 
    for filename in filenames: 
        if re.search('.xml', filename):
            #print(os.path.join(dirpath, filename))
            #xml files and py files are in the same directory
            parser.func(filename)

os.getcwd 获取当前文件所在路径,避免指定路径字符串。

用os.walk遍历当前文件夹,获取xml文件名。

因为得到的结果中会列出所有文件包括python脚本文件及xml名件,需要过滤掉py文件,因引入remodule匹配(.xml)文件。

parser.func 为步骤1,2中的处理过程。意思是找到一个xml文件,就按照步骤1,2处理一遍。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值