Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >关于带命名空间的中文XML的解析

关于带命名空间的中文XML的解析

作者头像
python与大数据分析
发布于 2022-03-11 05:55:41
发布于 2022-03-11 05:55:41
76200
代码可运行
举报
运行总次数:0
代码可运行

本来感觉XML文件解析是一件很简单的事情,结果折腾了一两周没什么进展,直到昨天才陆陆续续找到了一些解决方案,现在把踩坑过程和解决过程一并叙说一遍。

起因是源于项目中对XML的处理过程非常不满意,想着怎么把XML文件中的关键数据项找到并解析到关系数据库中,XML是SOA系统生成的,里面自然包含不少中文内容。

以前没做过完整的XML解析,按照最简单的例子对这个XML文件解析,发现总是报各种错误,却不知道问题在哪里,百度是最好的老师,发现有两点问题,一个是XML对字符集的识别相当不友好,另外一个是命名空间问题。

决定从最简单的XML文件-全英文无命名空间的XML开始,先解决命名空间问题-全英文带命名空间的XML,再解决-含中文带命名空间的XML。

一路跟过来,不断挣扎,不断踩坑,不断解决,不断前行,最终有一定进展。

english.xml

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<data>
    <customer name="wbq">
        <firstname>wang</firstname>
        <midname>bao</midname>
        <lastname>qiang</lastname>
    </customer>
    <country name="Liechtenstein">
        <rank>1</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank>4</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
    <country name="Panama">
        <rank>68</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>

namespacexml.xml

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?xml version="1.0"?>
<actors xmlns:fictional="http://characters.example.com"
        xmlns="http://people.example.com">
    <actor>
        <name>John Cleese</name>
        <fictional:character>Lancelot</fictional:character>
        <fictional:character>Archie Leach</fictional:character>
    </actor>
    <actor>
        <name>Eric Idle</name>
        <fictional:character>Sir Robin</fictional:character>
        <fictional:character>Gunther</fictional:character>
        <fictional:character>Commander Clement</fictional:character>
    </actor>
</actors>

chinesenamespace.xml

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <username>mk</username>
    <password/>
  </soap:Header>
  <soap:Body>
    <PublishCustomerTroubleTicketRequest xmlns="http://soa.csg.cn">
      <CustomerTroubleTicket>
        <influenceRange>singleFamily</influenceRange>
        <contactAddress>海南省</contactAddress>
        <faultLocation>海南省</faultLocation>
        <mRID>07000010000030535173</mRID>
        <servicekind>01</servicekind>
        <importance>ordinary</importance>
        <powerType>cityNetwork</powerType>
        <content>该户于1104日出现表不亮灯</content>
        <areaKind>cityCenter</areaKind>
        <ErpPersonRoles>
          <category>01</category>
          <ErpPerson>
            <name>先生</name>
          </ErpPerson>
        </ErpPersonRoles>
      </CustomerTroubleTicket>
    </PublishCustomerTroubleTicketRequest>
  </soap:Body>
</soap:Envelope>

代码实现:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import xml.etree.ElementTree as ET
import codecs
import re
from lxml import etree
#XML文件为英文可通过ElementTree直接解析
#XML文件以utf-8格式存储,可通过ElementTree直接解析
#XML文件以gb2312格式,解析会报错
#全英文无命名空间的XML
#全英文带命名空间的XML
#含中文带命名空间的XML

def replaceXMLEncoding(xmlfilename):
    #将gb2312的中文XML转码为utf-8格式
    try:
        f = open(xmlfilename, mode='r')
        content = f.read()                              #文本方式读入
        content = re.sub("GB2312", "UTF-8", content)    #替换encoding头
        f.close()
        f = open(xmlfilename, 'w')                      #重新以文本方式写入文件
        f.write(content)
        f.close()
        f = codecs.open(xmlfilename, 'rb', 'mbcs')      #二进制方式读入
        text = f.read().encode("utf-8")                 #使用utf-8方式编码
        f.close()
        f = open(xmlfilename, 'wb')                     #重新以二进制方式写入文件
        f.write(text)
        f.close()
    except:
        return

xmlfilename="english.xml"
# <data>
#     <customer name="wbq">
#         <firstname>wang</firstname>
#         <midname>bao</midname>
#         <lastname>qiang</lastname>
#     </customer>
#     <country name="Liechtenstein">
#         <rank>1</rank>
#         <year>2008</year>
#         <gdppc>141100</gdppc>
#         <neighbor name="Austria" direction="E"/>
#         <neighbor name="Switzerland" direction="W"/>
#     </country>
tree=ET.parse(xmlfilename)
root=tree.getroot()
print(tree)
#<xml.etree.ElementTree.ElementTree object at 0x0000018DF8C8DB38>
print(root)
#<Element 'data' at 0x0000018DF8B1E458>
print(root.tag)
#data
print(root.attrib)
#{}
#查找并打印根节点tag和属性值
for child in root:
    print(child.tag, child.attrib)
    # customer {'name': 'wbq'}
    # country {'name': 'Liechtenstein'}
    # country {'name': 'Singapore'}
    # country {'name': 'Panama'}
#查找并打印根节点中country标签的tag和属性值
for country in root.iter('country'):
    print(country.tag,country.attrib)
    # country {'name': 'Liechtenstein'}
    # country {'name': 'Singapore'}
    # country {'name': 'Panama'
##查找根节点中country标签,并打印其rank标签内容和name属性值
for country in root.findall('country'):
    rank = country.find('rank').text
    name = country.get('name')
    print(name, rank)
    # Liechtenstein 1
    # Singapore 4
    # Panama 68

xmlfilename="namespacexml.xml"
# <actors xmlns:fictional="http://characters.example.com"
#         xmlns="http://people.example.com">
#     <actor>
#         <name>John Cleese</name>
#         <fictional:character>Lancelot</fictional:character>
#         <fictional:character>Archie Leach</fictional:character>
tree=ET.parse(xmlfilename)
root=tree.getroot()
print(root)
#第一步遍历actor标签
for actor in root.findall('{http://people.example.com}actor'):
    #查找并打印actor name属性
    name = actor.find('{http://people.example.com}name')
    print(name.text)
    #查询下级character标签,并打印其标签值
    for char in actor.findall('{http://characters.example.com}character'):
        print(' |-->', char.text)

# 定义命名空间字典,简化查询操作
ns = {'real_person': 'http://people.example.com',
      'role': 'http://characters.example.com'}
for actor in root.findall('real_person:actor', ns):
    name = actor.find('real_person:name', ns)
    print(name.text)
    for char in actor.findall('role:character', ns):
        print(' |-->', char.text)

#解析带namespace的中文XML文件
# 定义命名空间字典,简化查询操作
# <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
#   <soap:Header><username>mk</username></soap:Header>
#   <soap:Body>
#     <PublishCustomerTroubleTicketRequest xmlns="http://soa.csg.cn">
xmlfilename="chinesenamespace.xml"
replaceXMLEncoding(xmlfilename)
tree=ET.parse(xmlfilename)
ns = {'topns': 'http://schemas.xmlsoap.org/soap/envelope/',
      'childns': 'http://soa.csg.cn'}
root=tree.getroot()
print(root)
# <Element '{http://schemas.xmlsoap.org/soap/envelope/}Envelope' at 0x000002168F7DC9F8>
#通过find一层层按照命名空间查找
body = root.find('topns:Body', ns)
print(body)
# <Element '{http://schemas.xmlsoap.org/soap/envelope/}Body' at 0x000002168F7DC9A8>
PublishCustomerTroubleTicketRequest = body.find('childns:PublishCustomerTroubleTicketRequest', ns)
print(PublishCustomerTroubleTicketRequest)
# <Element '{http://soa.csg.cn}PublishCustomerTroubleTicketRequest' at 0x000002168F7DC908>
CustomerTroubleTicket=PublishCustomerTroubleTicketRequest.find('childns:CustomerTroubleTicket',ns)
print(CustomerTroubleTicket)
# <Element '{http://soa.csg.cn}CustomerTroubleTicket' at 0x000002168F7DC8B8>
mRID = CustomerTroubleTicket.find('childns:mRID',ns)
print(mRID)
# <Element '{http://soa.csg.cn}mRID' at 0x000002168F7BA188>
print(mRID.text)
# 07000010000030535173

#用lxml.etree和xpath进行解析
xmlfilename="chinesenamespace.xml"
replaceXMLEncoding(xmlfilename)
xml = etree.parse(xmlfilename)
root = xml.getroot()
print(root)
#<Element {http://schemas.xmlsoap.org/soap/envelope/}Envelope at 0x1b067b124c8>
#通过xpath进行目录曾经查找
mRID=root.xpath('topns:Body/childns:PublishCustomerTroubleTicketRequest/childns:CustomerTroubleTicket/childns:mRID/text()',namespaces=ns)[0]
print(mRID)
#07000010000030535173

结论:

XML文件为英文可通过ElementTree直接解析

XML文件以utf-8格式存储,可通过ElementTree直接解析

XML文件以gb2312格式,解析会报错,需要将文件更改为utf-8格式编码

命名空间问题,可以通过find加命名空间的方式,也可以通过定义别名的方式

逐层查找是可以的,也可以通过xpath方式进行解析

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-11-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 python与大数据分析 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
python xml模块
xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,古时候,在json还没诞生的黑暗年代,大家只能选择用xml呀,至今很多传统公司如金融行业的很多系统的接口还主要是xml。
py3study
2018/08/02
5860
Python XML解析之Element
http://www.runoob.com/python/python-xml.html
py3study
2020/01/19
3.9K0
python xml.etree.El
We have a number of ways to import the data. Reading the file from disk:
py3study
2020/01/14
2820
python处理xml
XML格式类型是节点嵌套节点,对于每一个节点均有以下功能,以便对当前节点进行操作:
菲宇
2019/06/11
1.5K0
三十二、python操作XML文件
''' XML:模块 xml总结 1、解析 str 文件 tree,ElementTree,type root,Element,type 2、操作 Element: tag,text,find,iter,get,set... 3、重新写入 tree.write() str没有tree--->ElementTree(root) tree.write(xx,encoding='utf-8',xxx,xxx) 4、创建xml Eleme
py3study
2020/01/08
1K0
[接口测试 - 基础篇] 05 好讨厌的xml解析
概述 什么是XML? XML 指可扩展标记语言(eXtensible Markup Language)。 XML 被设计用来传输和存储数据。 XML是一套定义语义标记的规则,这些标记将文档分成许多部件并对这些部件加以标识。 它也是元标记语言,即定义了用于定义其他与特定领域有关的、语义的、结构化的标记语言的句法语言。 xml构成 XML由3个部分构成,它们分别是: 文档类型定义(Document Type Definition,DTD),即XML的布局语言 可扩展的样式语言(Extensible Style
苦叶子
2018/04/09
9970
Python指南:文件处理
哪种文件格式最适合用于存储整个数据集——二进制、文本还是XML?这严重依赖于具体的上下文。
王强
2018/08/09
1.3K0
Python指南:文件处理
python处理testlink
在软件活动中,我们需要对测试用例进行管理,如果只用excel,不用管理工具系统的管理,那么将出现以下一些问题: 案例文件分散,测试进度不透明; 需求变更导致的测试计划/测试用例变更,未能及时通知相关测试人员; 版本管理困难,很难追踪版本的变化; 缺陷管理与测试用例管理脱节,不便于缺陷密度的分析; 产品需求、测试计划、测试用例未能建立关联,不便于测试过程管理; 缺乏相关的测试分析报告数据,不便于暴露测试风险;
赵云龙龙
2019/09/03
2.2K0
python处理testlink
[快学Python3]XML解析处理 - Element Tree
概述 本文就是python xml解析进行讲解,在python中解析xml有很多种方法,本文通过实例来讲解如何使用ElementTree来解析xml。对于其他的xml解析方法,请自行去查找资料。 请注意,本文不是ElementTree手册,不会将所有的特性进行演示,笔者从实际用到的一些关键特性进行实例演示,对于其他特性,大家可以参见官方文档学习和了解: https://docs.python.org/3/library/xml.etree.elementtree.html 什么是ElementTree El
苦叶子
2018/04/09
2.9K0
Python 基于xml.etree.ElementTree实现XML对比
测试环境 Python 3.6 Win10 代码实现 #!/usr/bin/env python 3.4.0 #-*- encoding:utf-8 -*- __author__ = 'shouke' import xml.etree.ElementTree as ET def compare_xml_node_attributes(xml_node1, xml_node2): result = [] node1_attributes_dict = xml_node1.attrib
授客
2022/12/13
9160
Python学习--xml-Elemen
当你需要解析和处理 XML 的时候,Python 表现出了它 “batteries included” 的一面。 标准库 中大量可用的模块和工具足以应对 Python 或者是 XML 的新手。
py3study
2020/01/07
8660
N1CTF hard PHP Writeup
这个题目非常的有意思,做题的时候真的感觉到了php有多硬(hard被我强行翻译为硬)。
用户1879329
2023/02/27
2.5K0
N1CTF hard PHP Writeup
[935]python解析xml文件
XML 指可扩展标记语言(eXtensible Markup Language)。
周小董
2021/01/29
1.6K0
常用模块补充,内置函数,异常处理
shutil.copyfileobj(fsrc, fdst[, length]) 将文件内容拷贝到另一个文件中
py3study
2020/01/19
1.6K0
常用模块补充,内置函数,异常处理
WCF技术剖析之十八:消息契约(Message Contract)和基于消息契约的序列化
在本篇文章中,我们将讨论WCF四大契约(服务契约、数据契约、消息契约和错误契约)之一的消息契约(Message Contract)。服务契约关注于对服务操作的描述,数据契约关注于对于数据结构和格式的描述,而消息契约关注的是类型成员与消息元素的匹配关系。 我们知道只有可序列化的对象才能通过服务调用在客户端和服务端之间进行传递。到目前为止,我们知道的可序列化类型有两种:一种是应用了System.SerializableAttribute特性或者实现了System.Runtime.Serialization.I
蒋金楠
2018/01/16
1.7K0
Web Service进阶(一)运行原理[通俗易懂]
利用清明小假期,温习了一遍Web Service的相关内容,对其工作原理进行了简要总结。以供有需求的朋友和自己日后参考。文章若有不当之处,敬请朋友们提出宝贵建议,以求共勉。
全栈程序员站长
2022/09/15
5890
Web Service进阶(一)运行原理[通俗易懂]
Python全栈开发-常用模块学习
  模块:用来从逻辑上组织python代码(变量、函数、类、逻辑:实现一个功能),本质就是.py结尾的python文件(文件名:test.py,模块名就是:test)
公众号---人生代码
2019/09/09
8770
Python全栈开发-常用模块学习
简单入门例子:WebService客户端请求
1、例子1 package soapDemo; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; /** * 翻译TranslatorWebService * https://www.cnblogs.com/garfieldcgf/p/5966317.ht
程裕强
2022/05/06
8260
[转载] python 解析xml 文件
首先新建一个xml文件,countries.xml。内容是在python官网上看到的。
py3study
2020/01/19
1.4K0
python解析xml遇到的问题分享(命名空间有关)
要验证股票公司事件的数据入库规则,需要对开发的etl代码以及映射规则进行验证,然后数据源给的源文件格式是xml格式的,人工核对起来的话,考虑到有的字段还有枚举值映射关系或者一些简单的格式处理之类的,如果每次都人工去Ctrl + F去xml文件里面搜索标签去校验对应数据的话,效率不是特别的高,也不利于后续开发代码调整后的快速验证,因此我考虑自己用python脚本去按照分析师的规则文档自己解析一下xml文件,然后用自己解析出来的结果跟开发解析出来的数据进行一下对比,在一定程度上,能够稍微提升一下工作的效率。
小博测试成长之路
2022/12/02
9320
python解析xml遇到的问题分享(命名空间有关)
相关推荐
python xml模块
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验