• python解析xml遇到的问题分享(命名空间有关)


    024472d14a5e93045a93b07b8f3d4b29.png

    背景

    最近在工作中,要测试这样的一个需求:

    要验证股票公司事件的数据入库规则,需要对开发的etl代码以及映射规则进行验证,然后数据源给的源文件格式是xml格式的,人工核对起来的话,考虑到有的字段还有枚举值映射关系或者一些简单的格式处理之类的,如果每次都人工去Ctrl + F去xml文件里面搜索标签去校验对应数据的话,效率不是特别的高,也不利于后续开发代码调整后的快速验证,因此我考虑自己用python脚本去按照分析师的规则文档自己解析一下xml文件,然后用自己解析出来的结果跟开发解析出来的数据进行一下对比,在一定程度上,能够稍微提升一下工作的效率。

    0010f3c344334646a11d82a940ba562d.png

    过程&遇到的问题

    既然是要解析xml文件,我的第一反应是百度搜索“python xml解析” 

    9c2ab17987ed9ded3017e205ff2a0f52.png

    然后我选中了菜鸟教程中的一个文档进行查看:

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

    在页面中可以看到,包括一般百度到的文章介绍都是说有三种方式可以解析:

    38367f57216e814f07f2a9fdd67a6678.png

    接下来用一个案例去演示一下解析xml文件:

    测试案例的xml文件demo如下:

    1. "1.0"?>
    2. <corporate_actions
    3. xmlns="https://mp.weixin.qq.com/s/RGkBjpX5ipGHYNSOPaxktA" >
    4. <Students CLASSID="1" ID_REVISION="0000" ID_EVENT="12345678" xml:id="UCAEvent111212120000">
    5. <student name="小博">
    6. <classId>1classId>
    7. <year>2011year>
    8. <heigth>173heigth>
    9. student>
    10. <student name="张三">
    11. <classId>2classId>
    12. <year>2011year>
    13. <heigth>175heigth>
    14. student>
    15. Students>
    16. corporate_actions>

    接下来我们先写代码去获取Students这个标签的数据:

    ad032ccb87f64f1b7c66b80046aaa465.png

    然后很神奇的发现,直接用root.find去查找元素的时候,居然为空,看了网上的代码都是这么写的呀,一度陷入迷茫中。

    321fa4fd5bad1c83f1cdbcb4747b5281.png

    问题如何解决

    经过不断的搜索,最终看到别的小伙伴也遇到过这种问题:

    dd301ac90bcbdbf3312e079b1ee889af.png

    经过查找,发现在xml中,如果文件头中带有xmlns属性的话,表示这个是带有命名空间的,在解析的时候,要加上命名空间。

    关于xml的命名空间,可以参考下面的文章:

    https://www.w3school.com.cn/xml/xml_namespaces.asp

    1bb58169584ba1b0db78cb9befe5f581.png

    最终可以匹配到元素的代码如下:

    1. import xml.etree.ElementTree as ET
    2. xml_path = f"D:\\MyScripts\\PythonStudy\\QuotesApi\\ice.xml"
    3. tree = ET.parse(xml_path) # 打开xml文档
    4. root = tree.getroot()
    5. student1 = root.find("Students")
    6. student2 = root.find("{https://mp.weixin.qq.com/s/RGkBjpX5ipGHYNSOPaxktA}Students")
    7. print(student1) # 没加命名空间,匹配不到元素
    8. print(student2)  # 加了命名空间,匹配不到元素

    1eed1fb67e6a26a3711a9bd5358e32bc.png

    思考

    1、像上面那样写的话,每次定位元素都要在前面加上这么一长串的命名空间的代码,感觉有点冗余,有没有什么好的方式可以只写一次,后面不用写呢?(当然,为了测试方便的话,可以把xml文件中的命名空间的内容去掉即可)

    2、现在有现成的库可以直接把xml转dict,这样的话,在转换格式后可以借助jsonpath去提取文件中的数据,感觉比xml提取内容会方便一些。比如使用

    xmltodict库。

    学习/工作过程中有遇到问题的,可以加好友(xiaobotester)一起交流,需简单自我介绍下或者朋友圈对等开放。若一条都不满足,拒绝提供好友位,如需加测试讨论群,可以备注,融入圈子,一起成长。

  • 相关阅读:
    Ubuntu添加非root用户到Docker用户组
    WIN10商业版64位22H2正式版19045.2251MSDN11月原版镜像
    c#数组次序统计系列1
    解析字符串eval,new Function
    Vite - 配置 - 不同的环境执行不同的配置文件
    工业4.0 资产管理壳学习笔记(1)
    k8s-部署Redis-cluster(TLS)
    (附源码)计算机毕业设计SSM基于技术的高校学生勤工俭学管理系统的设计与开发
    从编译器对指令集的要求看API设计原则
    计算机毕业设计ssm+vue基本微信小程序的“香草屋”饮料奶茶点单小程序
  • 原文地址:https://blog.csdn.net/liboshi123/article/details/127781055