xml.etree.ElementTree处理xml文件并写入excel

1.city.xml

<ruzhi>
 <time year="2018">
  <user username="楠楠" jobname="硬件" cityname="成都">
    <hobbit>极限运动</hobbit>
  </user>
  <user username="谢科" jobname="芯片" cityname="江西"/>
  <user username="岳云" jobname="it软件" cityname="北京"/>
  <user username="婕婕" jobname="ui设计" cityname="上海">
    <hobbit>篮球</hobbit>
  </user>
  <user username="吴宇" jobname="ui设计" cityname="内蒙"/>
  <user username="乾泰" jobname="硬件" cityname="西昌">
    <hobbit>篮球</hobbit>
  </user>
  <user username="漱玉" jobname="it软件" cityname="南京"/>
  <user username="川川" jobname="it软件" cityname="南京"/>
 </time>
  <time year="2019">
  <user username="南杰" jobname="it软件" cityname="成都"/>
  <user username="智宇" jobname="ui设计" cityname="江西"/>
  <user username="清韵" jobname="it软件" cityname="成都">
    <hobbit>绘画</hobbit>
  </user>
  <user username="吴柳晨" jobname="芯片" cityname="上海"/>
  <user username="康宇" jobname="ui设计" cityname="成都"/>
  <user username="乾泰" jobname="硬件" cityname="西昌">
    <hobbit>拍视频、唱歌</hobbit>
  </user>
  <user username="佘琳" jobname="芯片" cityname="南京"/>
 </time>
 <time year="2020">
  <user username="谢玉玉" jobname="ui设计" cityname="成都"/>
  <user username="谢科" jobname="ui设计" cityname="江西"/>
  <user username="泽康" jobname="it软件" cityname="西昌">
    <hobbit>设计页面</hobbit>
  </user>
  <user username="闫旭" jobname="it软件" cityname="西昌"/>
  <user username="吴宇" jobname="ui设计" cityname="南京"/>
  <user username="尔林" jobname="it软件" cityname="西昌"/>
  <user username="杰夫与" jobname="硬件" cityname="南京">
    <hobbit>旅游</hobbit>
  </user>
 </time>
</ruzhi>

2.python脚本

#-*-coding:UTF-8-*-
import os,sys
import xml.etree.ElementTree as ET
import xlsxwriter

year_info={}

years={}
def open_xml(xml):
  #with open(xml) as xmls:#讲xml文件读取后转换为目标格式:只能针对英文xml
  #  xml_root=ET.fromstring(xmls.read()) #直接从字符串中解析 
  #  year=xml_root.findAll('time')
  #  for time in year:
  #    print("year is :"+time.get('year'))
  #
  #
  #
  #
  tree=ET.parse(xml)


  xml_root=tree.getroot()  #是所有节点的一个tree结构
  i=0
  for time in xml_root:
    print("节点tag是:"+time.tag+'\n' +"具体年份为 :"+time.get('year'))
    print("该年份内入职人个数为:",len(time))
    lenths=len(time)
    year=time.get('year') #获取time节点中属性year的具体值
    years[i]=year  #年份放入数组
    i+=1
    user_info={} #存放入职年份和入职人员信息
    for user in time:
      #user_info.clear() 不能这样清空  这个影响year_info数据
      print('员工的tag为'+user.tag+'\n'+'员工名字is :'+user.get('username')+'\n'+'员工工作类型 :'+user.get('jobname')+'\n'+'员工所在城市 :'+user.get('cityname')+'\n')
      #print(user.attrib['username'])  也是获取属性值的意思
      
      child=user.find('hobbit')
      if child is None:
        print("元素没有找到")
        user_info[user.get('username')]={'len':lenths,'job':user.get('jobname'),'city':user.get('cityname')}
      else:
        print("爱好是"+child.text)
        user_info[user.get('username')]={'len':lenths,'job':user.get('jobname'),'city':user.get('cityname'),'hobbit':child.text}
      #print('user job is :'+user_info['job']+'\n'+'user.city is :'+user_info['city']+'\n')
    year_info[year]=user_info
    user_info={}  #清空 这样清空不影响year_info字典数据
  print('最终的所有数据存放在字典中,如下:',year_info)
  
    
#对excel进行写入  xlsxwriter  只能处理新的excel文档 不能处理已经存在的文档

def get_all_user(xml):
  xml_root=ET.parse(xml).getroot()
  #user_node=xml_root.find('user')#find 找出来没有
  #user_node=xml_root.findall('user') #由元素但为空
  
  user_node=xml_root.find('time')  #user_node=xml_root.findall('time')找出来是list,在后面执行links时会报错
  if user_node is None:
    print("元素没有找到")
  else:
    print("存在user节点")
    print(user_node)
    links=list(user_node.iter('user'))
    print(links)
  
def input_data(excel,table):
  num=2
  num_year=2
  print('字典数据如下:',year_info)
  lenth=0
  for ids in years:
    print("当前所在年份为:",years[ids])
    a=True
    
    for user,userInfo in year_info[years[ids]].items():
      print('user is :',user)
      print('userInfo is :',userInfo)
      
      lenth=userInfo['len']  #年份合并单元格使用
      while a :
        num_years=num_year+lenth-1
        a=False
      table.merge_range('A'+str(num_year)+':'+'A'+str(num_years),str(years[ids]))
      
      table.write('B'+str(num)+':'+'B'+str(num+1),user)
      table.write('C'+str(num)+':'+'C'+str(num+1),userInfo['job'])
      table.write('D'+str(num)+':'+'D'+str(num+1),userInfo['city'])
      #dict内置的get(key[,default])方法,如果key存在,则返回其value,否则返回default,使用这个方法永远不会触发KeyError:
      #dict内置的setdefault(key[,default])方法,如果key存在,则返回其value;否则插入此key,其value为,并返回default;使用这个方法也永远不会触发KeyError
      if userInfo.get('hobbit'):  #判断是否有hobbit的key键 有的话返回其值
        table.write('E'+str(num)+':'+'E'+str(num+1),userInfo['hobbit'])
      num+=1
    print("num_year =",num_years)
    num_year=num_years+1
    
  
  
def make_xlsx(xlsx):
#  excel_file=xw.Workbook(xlsx,{'constant_memory':True})
  print(os.getcwd())
  if os.path.exists(xlsx+'.xlsx'):
    os.remove(xlsx+'.xlsx')
  excel_file=xlsxwriter.Workbook(xlsx+'.xlsx')
  print("excel file 创建成功!",excel_file)
  
  table=excel_file.add_worksheet('入职名单')
  
  title_format=excel_file.add_format({'border':2,'valign':'vcenter','bg_color':'blue','font_size':13})
  
  #table.merge_range('A1:B1',str('入职年份'),title_format) 合并单元格
  table.write('A1',str('入职年份'),title_format) 
  table.write('B1',str('姓名'),title_format)
  table.write('C1',str('职位'),title_format)
  table.write('D1',str('城市'),title_format)
  table.write('E1',str('爱好'),title_format)
  #table.merge_range('E1',unicode('爱好'),title_format)
  
  
  input_data(excel_file,table)  #存放数据
  
  
  excel_file.close()
  
  

  
if __name__=="__main__":
  #处理xml文件
  if len(sys.argv)<2:
    print("请传入你需要解析的xml!!")
  elif len(sys.argv)>2:
    print("传入参数过多!"+str(sys.argv))
  else:
    xml_file=sys.argv[1]
    open_xml(xml_file)
  #open(xml_file,'r')
  #open_xml(xml_file,'r') as xml:  普通方式打卡文件
    get_all_user(xml_file)
    
    #将解析的xml文件内容存放到xlsx文件内
    make_xlsx(xml_file.split('.')[0])  #创建文件

执行结果:
在这里插入图片描述

<think> 我们使用xml.etree.ElementTree库来创建XML文件。这个库是Python标准库的一部分,因此不需要额外安装。下面将详细介绍创建XML文件的步骤: ### 1. 创建根元素 使用`Element`函数创建根元素。 ### 2. 添加子元素 使用`SubElement`函数在根元素下添加子元素。 ### 3. 设置元素属性和文本 可以直接设置元素的属性和文本内容。 ### 4. 生成XML树 使用`ElementTree`类将根元素包装成XML树。 ### 5. 写入文件 使用`ElementTree`的`write`方法将XML写入文件。 ### 示例代码 ```python import xml.etree.ElementTree as ET # 创建根元素 root = ET.Element("catalog") root.set("company", "TechCorp") # 设置根元素属性 # 添加第一个book子元素 book1 = ET.SubElement(root, "book") book1.set("id", "101") # 在book1下添加title元素 title1 = ET.SubElement(book1, "title") title1.text = "Python编程" # 设置元素文本 # 添加第二个book子元素(带价格属性) book2 = ET.SubElement(root, "book") book2.set("id", "102") book2.set("price", "49.9") title2 = ET.SubElement(book2, "title") title2.text = "XML处理指南" # 创建ElementTree对象 tree = ET.ElementTree(root) # 写入文件(指定编码为UTF-8,避免中文乱码) tree.write("data.xml", encoding="utf-8", xml_declaration=True) # 可选:美化输出(ElementTree默认不缩进,我们可以通过添加换行和缩进来美化) # 由于标准库的ElementTree写入时不会自动格式化,我们可以通过以下方式实现基本美化: def indent(elem, level=0): """递归为XML元素添加缩进,使其输出更美观""" indent_str = "\n" + level*" " if len(elem): if not elem.text or not elem.text.strip(): elem.text = indent_str + " " if not elem.tail or not elem.tail.strip(): elem.tail = indent_str for child in elem: indent(child, level+1) if not child.tail or not child.tail.strip(): child.tail = indent_str else: if level and (not elem.tail or not elem.tail.strip()): elem.tail = indent_str # 调用美化函数 indent(root) # 重新写入文件(覆盖之前写入文件) tree.write("data.xml", encoding="utf-8", xml_declaration=True) ``` ### 生成XML内容 ```xml <?xml version='1.0' encoding='utf-8'?> <catalog company="TechCorp"> <book id="101"> <title>Python编程</title> </book> <book id="102" price="49.9"> <title>XML处理指南</title> </book> </catalog> ``` ### 关键点说明 1. **创建元素**: - `ET.Element(tag)` 创建根元素 - `ET.SubElement(parent, tag)` 在父元素下创建子元素 2. **设置属性**: - `element.set(key, value)` 设置元素属性[^1] 3. **设置文本**: - 直接给`element.text`属性赋值 4. **美化输出**: - 由于`ElementTree.write`默认不进行缩进,我们通过自定义`indent`函数递归添加缩进[^3] 5. **XML声明**: - `write`方法中`xml_declaration=True`参数确保生成XML声明头[^4] > ⚠️ 中文处理:务必指定`encoding='utf-8'`以避免乱码[^3]。 ### 替代方案:使用minidom美化 ```python # 若需要更美观的输出,可结合minidom from xml.dom import minidom # 将ElementTree元素转换为字符串 xml_str = ET.tostring(root, encoding='utf-8') # 用minidom解析美化 pretty_xml = minidom.parseString(xml_str).toprettyxml(indent=" ") with open("pretty.xml", "w", encoding="utf-8") as f: f.write(pretty_xml) ``` §§相关问题§§ 1. 如何使用xml.etree.ElementTree解析XML文件? 2. XML和JSON在Python中如何互相转换? 3. 如何处理XML命名空间(Namespace)? 4. 使用ElementTree修改现有XML文件的方法有哪些? </think># 使用xml.etree.ElementTree创建XML文件 `xml.etree.ElementTree`是Python标准库中处理XML的轻量级高效模块,特别适合创建和操作XML文档。以下是详细的创建方法: ## 基本创建步骤 ```python import xml.etree.ElementTree as ET # 1. 创建根元素 root = ET.Element("catalog") root.set("company", "TechCorp") # 设置属性 # 2. 创建子元素 book1 = ET.SubElement(root, "book") book1.set("id", "101") # 3. 添加元素内容 title1 = ET.SubElement(book1, "title") title1.text = "Python编程" # 设置文本内容 # 4. 创建树结构 tree = ET.ElementTree(root) # 5. 写入文件 tree.write("data.xml", encoding="utf-8", xml_declaration=True) ``` ## 完整示例(带格式化和命名空间) ```python import xml.etree.ElementTree as ET # 创建根元素(带命名空间) root = ET.Element("{http://example.com/books}catalog") root.set("company", "TechCorp") # 添加第一个book元素 book1 = ET.SubElement(root, "book", attrib={"id": "101"}) ET.SubElement(book1, "title").text = "Python编程" ET.SubElement(book1, "author").text = "John Doe" ET.SubElement(book1, "price").text = "39.99" # 添加第二个book元素(带更多属性) book2 = ET.SubElement(root, "book", id="102", category="advanced") ET.SubElement(book2, "title").text = "XML处理指南" ET.SubElement(book2, "author").text = "Jane Smith" ET.SubElement(book2, "price").text = "49.99" # 创建ElementTree对象 tree = ET.ElementTree(root) # 美化输出(自定义函数) def indent(elem, level=0): """递归添加缩进,使XML输出更美观""" indent_str = "\n" + level*" " if len(elem): if not elem.text or not elem.text.strip(): elem.text = indent_str + " " for child in elem: indent(child, level+1) if not elem.tail or not elem.tail.strip(): elem.tail = indent_str else: if level and (not elem.tail or not elem.tail.strip()): elem.tail = indent_str # 应用美化 indent(root) # 写入文件(带XML声明) tree.write("books.xml", encoding="utf-8", xml_declaration=True, method="xml", short_empty_elements=False) # 确保空元素正确关闭 ``` ## 生成XML文件内容 ```xml <?xml version='1.0' encoding='utf-8'?> <catalog xmlns="http://example.com/books" company="TechCorp"> <book id="101"> <title>Python编程</title> <author>John Doe</author> <price>39.99</price> </book> <book category="advanced" id="102"> <title>XML处理指南</title> <author>Jane Smith</author> <price>49.99</price> </book> </catalog> ``` ## 关键方法说明 1. **创建元素**: - `ET.Element(tag, attrib={})` - 创建根元素 - `ET.SubElement(parent, tag, attrib={})` - 创建子元素 2. **设置元素属性**: ```python element.set("attribute_name", "value") # 方法1 element = ET.Element("book", {"id": "101"}) # 方法2 ``` 3. **添加文本内容**: ```python title = ET.SubElement(book, "title") title.text = "Python编程" # 设置文本内容 ``` 4. **美化输出**: - `ElementTree`默认不缩进输出,使用自定义`indent()`函数可格式化XML[^1] 5. **XML声明与编码**: ```python tree.write("data.xml", encoding="utf-8", xml_declaration=True) # 生成XML声明 ``` 6. **命名空间处理**: ```python # 注册命名空间 ET.register_namespace('', "http://example.com/books") # 创建带命名空间的元素 root = ET.Element("{http://example.com/books}catalog") ``` ## 注意事项 1. **中文编码**: - 必须指定`encoding="utf-8"`避免中文乱码[^3] 2. **空元素处理**: - 设置`short_empty_elements=False`确保空元素正确关闭: ```xml <element></element> # 替代 <element/> ``` 3. **文件写入模式**: - Python 3.x推荐使用`encoding="utf-8"` - Python 2.x可能需要使用`"w"`模式而非二进制写入
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值