zoukankan      html  css  js  c++  java
  • Python自带xml模块实现xpath查询带xmlns命名空间的xml

    需求

    手上有个项目需要解析xml数据,参考写爬虫的经验,容易想到使用XPath语句进行节点导航。

    XPath 是一门在 XML 文档中查找信息的语言,用于在 XML 文档中通过元素和属性进行导航。
    XPath 使用路径表达式来选取 XML 文档中的节点或者节点集。这些路径表达式和我们在常规的电脑文件系统中看到的表达式非常相似。

    查阅

    网上搜了一下,大多推荐使用lxml模块而非自带的xml进行查询,三方库确实强大,但lxml需要单独安装,通用性不足,希望尽量用系统自带的xml实现。

    文档指出xml.etree.ElementTree可以通过支持的有限的XPath表达式来定位元素,支持语法如下:

    语法 说明
    tag 查找所有具有指定名称tag的子元素。例如:country表示所有名为country的元素,country/rank表示所有名为country的元素下名为rank的元素。
    * 查找所有元素。如:*/rank表示所有名为rank的孙子元素。
    . 选择当前元素。在xpath表达式开头使用,表示相对路径。
    // 选择当前元素下所有级别的所有子元素。xpath不能以“//”开头。
    .. 选择父元素。如果视图达到起始元素的祖先,则返回None(或空列表)。起始元素为调用find(或findall)的元素。
    [@attrib] 选择具有指定属性attrib的所有子元素。
    [@attrib='value'] 选择指定属性attrib具有指定值value的元素,该值不能包含引号。
    [tag] 选择所有具有名为tag的子元素的元素。
    [.='text'] Python3.7+,选择元素(或其子元素)完整文本内容为指定的值text的元素。
    [tag='text'] 选择元素(或其子元素)名为tag,完整文本内容为指定的值text的元素。
    [position] 选择位于给定位置的所有元素,position可以是以1为起始的整数、表达式last()或相对于最后一个位置的位置(如:last()-1)

    上述完全能够涵盖我的查询工作,决定实现。

    实现

    代码如下

    import xml.etree.cElementTree as ET
    
    tree = ET.ElementTree(file="./reference.kml")
    marks = tree.findall(".//Placemark")
    

    注意这里的XPath不支持直接用//而要写作.//
    上述代码没有报错,但返回list始终为[]无法匹配节点

    思考

    进入debug console查看tree变量显示存在根节点,也可以用tree[0][1][2]进行导航,我???
    查看tag名称显示为{http://opengis.net/kml/2.2}XXX比较奇怪

    此时xml文件开头的<kml xmlns="http://opengis.net/kml/2.2">引起了我的注意
    这不就是tag里多出来的字段?

    进一步查阅,xmlns全称为xml namespace类似C++的命名空间,用于解决局部名称重复冲突。
    进一步的,存在xmlns则需要在XPath查询时指定namespace字典进行导航。

    解决

    添加namespaces属性即可

    import xml.etree.cElementTree as ET
    NS = {"i":"http://opengis.net/kml/2.2"}
    tree = ET.ElementTree(file="./reference.kml")
    marks = tree.findall(".//i:Placemark",namespaces=NS)
    

    查询正常,能够返回匹配的list结果。

  • 相关阅读:
    for循环中创建线程执行问题
    MySQL学习总结之路(第六章:表类型【存储引擎】的选择)
    Tensorflow的下载和安装
    C# 和 Python 的 hash_md5加密方法
    MySQL学习总结之路(第五章:函数)
    MySQL学习总结之路(第四章:运算符)
    MySQL学习总结之路(第三章:数据类型)
    MySQL学习总结之路(第二章:表)
    MySQL学习总结之路(服务与数据库管理)
    CSS居中的方式15种(水平垂直)
  • 原文地址:https://www.cnblogs.com/azureology/p/13144388.html
Copyright © 2011-2022 走看看